There's an old line in cooking that chefs repeat a lot: we eat with our eyes first.
Before you taste anything, before the waiter describes the dish, before you even pick up a fork, you see the plate. How it's composed, the colors, the empty space, how precise it is. All of that tells you something about the kitchen. A carefully plated dish says someone cared. A sloppy one says the opposite.
A personal portfolio works the same way. A recruiter, a potential client or a CTO looking for a senior engineer has seen hundreds of them. Within a few seconds of landing on yours they've already formed an opinion, and it isn't about your skills yet. It's about how professional you seem.
This post is about that first impression: what creates it, why it matters so much for a portfolio, how to build it on purpose with a design system, and what I learned redesigning mine from scratch.
Two restaurants
Picture two places you could go for dinner tonight.
The first has mismatched chairs, a menu set in three different fonts, staff in whatever they happened to wear, and plates that look thrown together. The food might be great, but you're already a bit unsure.
The second has a clear look: dark wood, warm light, a menu with a consistent palette, staff dressed alike, food plated with obvious intent. You haven't tasted anything and you already trust them.
That's visual language: the sum of every design choice, deliberate or not, that tells people who you are and how you work.
For a portfolio that technical recruiters, engineering managers and clients will see, this matters a lot. These are people who judge attention to detail for a living. They notice when something is off, even if they can't say exactly what. Your design language doesn't just make the site look nice. It shows how you think about problems, how you handle complexity and how much you care about what you ship.
Design language vs design system
A design language is the set of visual rules that decide how everything in your interface looks and behaves:
- Typography: which fonts, at what sizes, with what weight hierarchy
- Color: primary, secondary, neutrals and semantic colors (error, success, warning)
- Spacing: consistent rhythm between elements, padding scales, grids
- Motion: how things animate, how fast, with which easing
- Tone: the personality the design gives off (minimal, bold, playful, serious)
When those are consistent and deliberate, the interface feels coherent. When they aren't, it feels amateur, even if every individual component is well built.
A design system is how you implement that language in code: the component library, the design tokens, the documented patterns and the shared rules that keep things consistent as the project grows. If the design language is knowing the recipe, the design system is having a professional kitchen to cook it in every night.
Typography tells a story
Of all the design decisions in a portfolio, typography is both the most underrated and the one with the biggest effect. Most developers pick a font quickly and move on. That's a mistake, because fonts have personality.
A geometric sans like Unbounded reads as precise and technical. A neo-grotesque like Inter feels neutral and professional. A serif like Playfair Display brings an editorial warmth. Pick the wrong one and the site sends a mixed message before anyone reads a word.
Why there are so many
Typefaces were made for very different jobs (newspapers, signage, advertising) and they carry those personalities into screens today. The categories that matter for a portfolio:
- Display / headlines: lots of personality, used big. Unbounded, Space Grotesk, Cabinet Grotesk. These set your brand's character.
- Body / reading: built for small sizes. Outfit, Inter, DM Sans. They should disappear into the text.
- Monospace: for code. JetBrains Mono, Geist Mono.
Choosing and pairing
The rule that works almost every time: pair a display font with personality with a neutral, readable body font. Let the headline carry the character and let the body carry the words.
When I wrote this, the site used Unbounded for headlines and Outfit for body text. Unbounded is geometric and bold, technical but modern. Outfit has a generous x-height and gets out of the way in long posts. Together they gave a clear hierarchy without fighting each other.
A few practical notes: two families at most, because more is noise. Test readability at real body size, around 15 to 16px with a line height of 1.6 to 1.7. And use next/font/google so the fonts are self-hosted and don't cause layout shift.
Oliver Reichenstein once argued that web design is 95% typography. It's an exaggeration, but not by much. Get it right first.
Before you write code: mockups and flows
The workflow mistake I see most in developer portfolios is jumping straight into code with no visual plan. The design then evolves at random: each new section has slightly different spacing, headings don't match in size, hover states don't match anything.
The best investment you can make before building is a mockup. It doesn't have to be pixel-perfect, but some visual plan, even rough wireframes, forces decisions that are much cheaper in a design tool than in code.
There are three levels. Wireframes are low-fidelity structure, boxes and labels, answering "what goes where?". Mockups are high-fidelity static screens with real colors, fonts and spacing, answering "what does it actually look like?". Prototypes are interactive flows with transitions, answering "how does someone move through this?". For a portfolio, wireframes and mockups are the minimum; prototypes are worth it for complex interactions like navigation drawers or multi-step forms.
Then map the flows, meaning how people move between screens and states. For a portfolio the important ones are: from the hero into the sections (what pulls the eye down the page?), from a project card into its detail page, from the blog list into a post and then related posts, and how navigation works on mobile. Drawing these first saves you from finding out three weeks in that your navigation makes no sense on a 375px screen.
The tools I use: Figma, the industry standard and free for solo work, for design, prototyping and inspecting in one place. Whimsical for quick wireframes and flow diagrams before committing to Figma-level detail. And Mobbin, a collection of UI patterns from real production apps, which is a great reference for how common interactions are usually done.
Why it matters even more in a portfolio
A generic company website can get away with inconsistent design. A developer's portfolio can't, because the people evaluating you deal with craft every day. A misaligned button state, a heading scale that's slightly off, a color a shade wrong: it registers, maybe not consciously, but it does.
Your portfolio is making three arguments at once. That you're technically capable, which your projects and the technologies you know prove. That you have good taste, which the site itself proves. And that you pay attention to detail, which shows in the consistency of every interaction. The second and third arguments are made entirely by your design language, before anyone reads a line of your bio.
For recruiters in particular, a polished, intentional portfolio shortens the trust gap. They've seen so many rushed ones that a well-designed site immediately stands out, and it suggests you put the same care into your work as into how you present it.
It opens doors, but only if it shows the work
A beautiful portfolio with empty or badly documented projects is a gorgeous restaurant with no food. The visual language earns trust; the content has to back it up.
This is where developers often go wrong: listing projects isn't the same as presenting them. A GitHub link and one line of description isn't a presentation. Recruiters, managers and CTOs look at your projects with specific questions in mind, and your portfolio either answers them or it doesn't:
- What problem did it solve? Not the stack, the actual user or business problem.
- What exactly did you do? Especially important on team projects.
- What were the interesting technical challenges? This is where seniority shows.
- What does it look like, and does it work? Screenshots, live demos and videos aren't optional.
- What would you do differently? It shows self-awareness and that you keep learning.
A project that answers all five tells a complete story. Recruiters go through dozens of portfolios in a morning, and the ones they remember are the ones that told a story.
It compounds
Every well-documented project is lasting proof of what you can do. It doesn't expire, it doesn't disappear when you leave a company, and nobody has to take your word for it. Anyone can look at it in a minute and a half.
That counts even more with how hiring works now. With remote-first hiring, your portfolio is often the only concrete thing someone sees before a first call. With async screening, it gets evaluated when you're not in the room, so the copy, the structure and the project write-ups have to do all the work. And for international roles, a portfolio that's visually professional and clearly written, in more than one language, reaches a lot further.
I've had opportunities come straight from people finding my portfolio, not from applications I sent but from someone landing on the site and reaching out. That only happens when the portfolio is worth finding.
Presenting projects well
Lead with the outcome, not the tech: "built a real-time collaborative whiteboard used by 3,000 people" lands harder than "built with React, WebSockets and Redis". Show it running; a live demo or a screen recording beats ten screenshots. Be specific about your role: "led the frontend architecture" says more than "worked on the frontend". And include the messy parts: the problems you hit, the constraints, the trade-offs. How you talk about those is a big part of what separates senior engineers from junior ones.
The UI/UX rules that quietly run everything
You don't need a design degree to follow the principles that make an interface feel right, but you do need to know they exist.
Visual hierarchy. Everything on the page is implicitly ranked. Size, weight, color and position create that ranking. Your name should be the biggest thing in the hero, section labels smaller than headings, body text smaller than both. If everything is the same size, nothing matters.
Contrast. WCAG AA asks for at least 4.5:1 for normal text. Amber on near-black (#f59e0b on #0f0f11) is close to 9:1, which is excellent. Light gray on white often fails. Check every text color against its background.
Spacing rhythm. Inconsistent spacing is the most common mistake in developer portfolios. Use an 8px base and build every gap from multiples of it: 8, 16, 24, 32, 48, 64. Tailwind's default scale already works this way. Stick to it and your layouts will feel settled even before any polish.
The fold. What people see without scrolling is your most valuable space. The hero has to say who you are, what you do and why they should keep reading before anyone touches the scroll wheel.
Mobile first. Around 60% of web traffic is mobile. A portfolio designed for desktop and then "adapted" usually shows it. Design the mobile layout first and expand from there.
Cognitive load. Every element costs the user some attention. Remove anything that doesn't serve what they came for. A few elements done well always beat many done carelessly.
The technical side: a design system from day one
Most developers think about design systems too late. You build the thing, ship it, and then try to bolt consistency onto a codebase that was never meant for it. You end up with one-off styles, magic numbers and components that all look slightly different for no reason. Starting with a design system, even a minimal one, changes that.
Step 1: design tokens
Tokens are the atomic values of the system: named variables for colors, spacing, font sizes, border radii and so on. With CSS and Tailwind they live in your config and become the shared vocabulary between design and code.
The key decision is how you store the values. Storing colors as space-separated RGB channels in CSS variables, instead of hardcoded hex, gives you Tailwind's opacity modifiers for free:
/* globals.css */
:root {
--primary: 217 119 6; /* amber, channel format */
--background: 15 15 17;
--foreground: 234 237 245;
}
// tailwind.config.ts
colors: {
primary: 'rgb(var(--primary) / <alpha-value>)',
background: 'rgb(var(--background) / <alpha-value>)',
}
Now bg-primary/10 gives you a 10% amber tint and text-primary/60 gives you text at 60% opacity, with no extra tooling. And changing the primary color across the whole site is one variable.
Step 2: the type scale
Define your typefaces and hierarchy before writing a single component. next/font/google self-hosts them and avoids layout shift:
import { Unbounded, Outfit } from 'next/font/google';
const headline = Unbounded({ subsets: ['latin'], variable: '--font-headline' });
const body = Outfit({ subsets: ['latin'], variable: '--font-body' });
fontFamily: {
headline: ['var(--font-headline)', 'sans-serif'],
body: ['var(--font-body)', 'sans-serif'],
}
Step 3: a component library, where it really pays off
This is where most tutorials stay at the surface, but a real component library is what turns a design system from an idea into something that keeps paying you back.
In practice it's a set of self-contained UI primitives with fixed, opinionated APIs that enforce your design rules everywhere they're used. Each component is the single source of truth for how that pattern looks and behaves across the app. The backbone of this portfolio's:
Button: variants (primary, secondary, ghost), accents, sizes and an optionalhref. Every call to action goes through it.Title: wraps heading tags with the right font, weight and an optional gradient.<Title as="h2" gradient="amber">covers it.SectionLabel: the small uppercase, tracked text above section headings. One component, the same everywhere.AccentCard: a bordered card with a tinted background, using the CSS tokens directly.Pill: technology tags and status badges, with accent support.
The rule that makes it work: design system components don't accept arbitrary color overrides. They have variant and accent props. If you need a new visual state, you add it to the component, never override it where it's used. That's what actually enforces consistency.
And the payoff compounds. When I decided to make amber the only accent color, I didn't hunt through 40 files. I changed one CSS variable and it reached every component at once. Something that could have taken days took minutes. Looking ahead, it also means that if I want to redesign the site with a different color direction or typographic personality, the architecture makes that easy: the tokens change, the component APIs and the content stay the same, and only the visual layer moves.
Step 4: write the rules down
Even on a solo project, writing your design decisions down forces you to be clear. "Amber is the only accent color." "Every CTA uses the Button component." "No inline styles except for dynamic values." Rules that aren't written down get forgotten.
The redesign: from cartoonish to professional
My portfolio went through a redesign that turned out to matter more than I expected.
The previous version had what I'd call a cartoonish spirit: bright indigo and purple gradients, a more playful energy, and accent colors used inconsistently from page to page. It was fun to build and I liked it at the time. But as my career moved on I started to notice the mismatch. The design said "cool side project" while my work said "senior engineer with more than six years in production". That gap was costing me credibility.
The decision that changed everything was simple: pick one accent color and use it everywhere. I went with amber. Not because amber is objectively better than indigo, but because committing to a single accent and enforcing it in every component, every hover state, every button, every section label and every Open Graph image is what makes a site feel coherent.
From there the system almost designed itself: near-black backgrounds (#0f0f11) that feel calm and focused, two typefaces with clear roles (Unbounded for headlines, Outfit for body), amber as the only accent and used sparingly, a component library (Button, Title, Text, SectionLabel, Pill, AccentCard), and consistent motion with short, purposeful GSAP animations.
The result wasn't just a prettier site. It made a completely different first impression. The portfolio stopped looking like a side project and started looking like the work of a senior engineer. Every page, from blog posts to the privacy policy, the error pages and even the offline fallback, follows the same visual rules. That consistency isn't luck; it comes from having a design system.
What I learned working with designers
My most important design education didn't come from tutorials or books. It came from working next to designers and UI/UX specialists, and it permanently changed how I write frontend code.
There's a particular kind of learning that happens when a designer opens Figma, points at a component and explains not just what it should look like but why. Why a 4px gap and not 8px. Why that shade of amber and not a brighter one. Why the button radius is 12px and not 8 or 16. They're deliberate decisions with reasons behind them, and understanding those reasons changes how you code.
Designers think in states and transitions, while developers tend to think in components and props. A designer specs a button with hover, active, focus, disabled and loading states, because all of those are part of the experience. A developer might build the default state and move on, and the result works but doesn't feel right.
They also treat whitespace as a design element, not as missing content. Empty space is deliberate: it gives things room, groups related elements and guides the eye. Learning to resist filling every pixel was one of the most useful things I took from those teams.
These days the handoff between design and development happens through tokens. Designers define them as Figma variables and developers implement them in CSS. When both sides share the same vocabulary (color.primary, spacing.md, radius.card), going from design to code loses almost nothing. That's why a token-based system is worth it even when you work alone: you're learning the language every modern design team speaks.
The biggest change for me was understanding that design isn't decoration. Every visual decision is a UX decision. The button color says "you can click this". The font size says what matters most. The spacing says what belongs together. Once you think of design as a communication layer instead of an aesthetic one, your code gets better. You stop making arbitrary visual choices and start asking what this communicates, and to whom.
Good practices make it incremental
What nobody mentions about design systems is that they don't just make a project look better. They make it easier to evolve.
When every component belongs to a system, every improvement is inherited everywhere. Changing the accent color means changing one token. Fixing the button hover state means fixing one component. Adding a page means assembling pieces you already have. New features don't add visual debt, performance work like lazy loading, code splitting or server rendering is easier with purpose-built components, and small changes have a big reach.
The same goes for other good practices in the stack. Semantic HTML and accessible components improve screen reader support and SEO at the same time. Clean structured data and a tidy sitemap improve indexing over time. A bilingual content structure makes translation something you add, not a rewrite. None of this means doing more work. It means doing the right work once, in the right place.
Where I look for inspiration
One of the most common questions from developers working on a portfolio is "how do I know what looks good?" The honest answer is exposure. You train your eye by looking at a lot of good design. These are the places I keep going back to:
- Awwwards: award-winning sites with a very high bar. Spend an hour there and you'll feel the difference between good and great.
- Dribbble: shots from designers everywhere. Good for exploring color, component ideas and micro-interactions. Don't copy; figure out why something works.
- Behance: full case studies, not just final screens. Useful for understanding process and decisions.
- dark.design: a curated gallery of dark-mode sites, if that's the direction you're going.
- bestfolios.com: developer and designer portfolios you can filter by role and style.
- Mobbin: real UI patterns from top web and mobile apps, great for researching how a specific interaction is usually handled.
- Linear: often held up as one of the best examples of dark-mode product design. Worth studying closely.
It also helps to follow designers and engineers at companies known for design quality, like Vercel, Linear, Stripe and Notion, whose work sets the current bar, and the design community on X, where people constantly share their process and references.
The bigger lesson: when something works, a spacing decision, a color treatment, a hover interaction, ask yourself why. Don't just collect references. Understand the principle behind them and you'll be able to apply it in contexts that look nothing like the original.
The plating counts
The chefs I admire most treat plating as part of the cooking. The dish isn't done when it's cooked; it's done when it's served.
A portfolio is the same. Your skills are the cooking and your design language is the plating. Both matter and both say something about you. Typography with personality, mockups before code, the UI/UX principles behind every interface that feels right, a component library that makes redesigns easy, learning from designers and looking for inspiration on purpose: none of it is about making things pretty. It's about making them right, structurally sound, visually coherent and built to change.
A solid design language backed by a real design system tells people you think in systems, you care about consistency, and you're building something that lasts, not just shipping features. When hiring decisions happen at a glance and a recruiter is reviewing fifty portfolios on a Tuesday morning, your visual language is your handshake.
Update, October 2026: the next redesign
A few months after writing this, I redesigned the site again, and it was the best test of everything above. The new system is called Lumen: light neutral grounds with a dark theme, rounded surfaces, Geist instead of Unbounded and Outfit, spring motion tied to scroll, and amber (#D97706) still as the only accent. Because colors, spacing and type already lived in tokens, the content didn't have to change at all. The work went into the visual layer: new tokens, new components and a rebuilt home page.
This portfolio is open source
Everything in this post, the design system, the tokens, the component library, the animations and the bilingual blog, is public under the MIT license. You can use it, fork it, adapt it and build your own version.
→ github.com/listerineh/personal-portfolio
If the code, this post or any of these patterns helped you, a star on the repo goes a long way. It helps other people find it and keeps me motivated to keep documenting and improving it.
What did you think?
Found this article helpful? Share it!
Help others discover this content by sharing it on your favorite platform.



