I built a zero-dependency portfolio template — here's what I learned
Source: Dev.to
Why a Zero‑Dependency Template?
- Designer‑friendly – No JSX, no components, no state management. Just plain HTML files you can open in a browser.
- No build step – Edit a file, refresh the browser. Done.
- Future‑proof – No deprecated packages, no breaking updates, no npm audit warnings.
- Tiny footprint – 300 KB total (the whole template, not just the JavaScript bundle).
- Bilingual support – Russian and English with a language switcher, easy to adapt for any two languages.
- Dark mode – Toggle button + automatic system preference, saved in
localStorage. - Case‑study layout – Numbered sections, stats grid, image lightbox with zoom, previous/next navigation.
- Terminal easter egg – Press
~for a secret terminal with design quotes. - Design‑system overlay – Press
Shift+Gto see the 12‑column grid. - One‑command setup –
./setup.shasks for your name, generates a favicon, replaces all placeholders. - SEO ready – Open Graph, JSON‑LD, sitemap, canonical tags,
hreflang. - Accessible – ARIA, keyboard navigation,
focus-visible, reduced‑motion support.
Quick Start
git clone https://github.com/diyoriko/portfolio-template.git my-portfolio
cd my-portfolio
./setup.shThe script prompts for:
- Your name
- Domain
- Social links
It then:
- Replaces the placeholder “Jane Smith” everywhere.
- Generates an SVG favicon with your initial.
- Updates
CNAME,sitemap, andconfig.json.
After the setup, commit the changes and push to GitHub Pages.
Dark‑Mode Architecture
I started with only prefers-color-scheme but quickly realized users want a manual toggle. The final solution uses a dual system:
/* Automatic mode */
@media (prefers-color-scheme: dark) {
:root:not(.light) {
/* dark theme variables */
}
}
/* Manual toggle */
html.dark {
/* dark theme variables */
}Lesson: The CSS ends up duplicated. Next time I’d use CSS layers or a single class‑based approach from the start.
Handling Hard‑Coded Colors
My first pass scattered rgba(0, 0, 0, 0.08) for borders and shadows. In dark mode those values became invisible, so I replaced them with CSS custom properties:
:root {
--border-color: rgba(0, 0, 0, 0.08);
}
/* Dark mode override */
html.dark {
--border-color: rgba(255, 255, 255, 0.12);
}Lesson: Define variables from day one, even for “obvious” values.
Demo & Resources
- Live demo: diyor.design (built with the same code)
- GitHub repository: – fork, clone, or use the “Use this template” button
- One‑click deploy: GitHub template ready to go on GitHub Pages
License
The template is released under the MIT License. If you build something with it, I’d love to see your work!