Every developer eventually reaches a point where a GitHub profile and a LinkedIn page just don't cut it anymore. You need a home on the web that's entirely yours — one that loads fast, ranks on Google, and makes hiring managers stop scrolling. This is how I built mine, and everything I learned along the way.
Why Build From Scratch?
There are plenty of portfolio templates out there. Framer, Webflow, even plain HTML themes. I chose to build from scratch for two reasons: I wanted full control over performance, and I wanted the portfolio itself to be a demonstration of my skills. If I'm pitching myself as a Next.js developer, the portfolio should be built with Next.js.
It also doubles as a live code sample. Any client or recruiter can inspect the network tab and see sub-second load times, or view the source and find clean, typed code.
The Tech Stack
I kept the stack lean and production-grade:
- Next.js 15 (App Router) — Server components, file-system routing, and built-in metadata API make SEO effortless.
- TypeScript — Non-negotiable. It catches errors at compile time and serves as living documentation.
- Tailwind CSS v4 — Utility-first CSS with zero runtime overhead. The new v4 alpha uses a CSS-native approach that eliminates the config file entirely.
- Geist fonts — Vercel's typefaces designed specifically for developer tools. Clean, modern, and fast because they're loaded via
next/fontwith automatic self-hosting. - Vercel — Zero-config deployments, edge CDN, and automatic HTTPS. There's no better hosting for a Next.js site.
Design Philosophy: Dark, Sharp, Intentional
Most developer portfolios look the same — white backgrounds, Inter font, hero section with a headshot. I wanted something that felt more like a terminal than a brochure.
The design anchors around two colors: near-black #080808 as the background, and yellow #facc15 as the sole accent. This constraint forces discipline. Every yellow element must earn its place — a hover state, a highlighted skill, an active link. The result is a UI with strong visual hierarchy without needing a full design system.
Motion is subtle and purposeful. Floating background orbs, a scan-line animation on the hero, and entrance animations that use animation-delay to stagger content into view. Nothing auto-plays endlessly in a way that distracts from reading.
SEO Strategy for Developer Portfolios
Most developers treat SEO as an afterthought. That's a mistake. Search traffic is the only acquisition channel that compounds over time. Every blog post or project page you publish is a permanent asset that can drive inbound leads for years.
Metadata and Open Graph
Next.js has a first-class Metadata API that generates all your <meta> tags at build time. I export a metadata object from every page with a title template, description, Open Graph image, and Twitter card. This ensures every shared link looks professional on Slack, Twitter, and LinkedIn.
The title field uses a template: %s | Kuba Nowacki. Individual pages provide the %s part, and the root layout appends the brand name. This gives every page a unique, descriptive title without repetition.
Structured Data (JSON-LD)
Structured data tells search engines exactly what your content is. I added two Schema.org schemas:
- Person schema in the root layout — name, job title, known skills, and
sameAslinks to GitHub and LinkedIn. - BlogPosting schema on each article — headline, description, author, publish date, and canonical URL.
These schemas enable rich results in Google Search — things like author bylines, article dates, and knowledge panel connections. You can validate your markup for free with Google's Rich Results Test.
Sitemap and Robots
Next.js can generate a sitemap and robots.txt automatically using special sitemap.ts and robots.ts files in the app/ directory. My sitemap includes all static routes plus every blog post, each with a changeFrequency and priority hint for crawlers.
Submit your sitemap to Google Search Console after deployment. It typically takes 1–2 weeks for pages to be fully indexed, but the sitemap accelerates discovery.
Core Web Vitals and Performance
Google uses Core Web Vitals as a ranking signal. The three metrics that matter most are:
- LCP (Largest Contentful Paint) — How fast the main content loads. Target: under 2.5 seconds.
- INP (Interaction to Next Paint) — How responsive the page is to user input. Target: under 200ms.
- CLS (Cumulative Layout Shift) — How stable the layout is during load. Target: under 0.1.
Next.js helps with all three out of the box. Server components eliminate client-side JavaScript waterfalls. next/font prevents layout shift from font swaps by self-hosting fonts and injecting size-adjust values. Images served with next/image are automatically optimized, converted to WebP, and include width/height attributes that reserve space before they load.
For my portfolio specifically, I kept the JavaScript bundle minimal. Only interactive components — the navbar scroll listener and the TypeWriter animation — are client components. Everything else is a server component with zero JS.
Backlinks: Building Authority Over Time
On-page SEO gets you indexed. Backlinks get you ranked. A backlink is any external site linking to yours, and Google treats them as votes of confidence.
As a developer, you have natural backlink opportunities that most people overlook:
- GitHub profile — Add your portfolio URL to your GitHub bio. GitHub pages rank well and pass link equity.
- LinkedIn — Add your site URL to your profile. LinkedIn is a high-authority domain.
- npm packages — If you publish packages, link to your site in the
homepagefield ofpackage.json. - Open source contributions — When you contribute to repos, your GitHub profile (which links to your site) gains visibility.
- Technical blog posts — Writing useful content that other developers reference is the highest-quality backlink source. Start with dev.to or Hashnode, cross-post there, and link back to the canonical version on your own site.
- Conference talks and podcast appearances — Even local meetup talks often include a speaker page that links back to you.
Blog as an SEO Multiplier
A portfolio homepage can realistically rank for one or two keyword combinations — usually your name and maybe "[your name] developer." A blog multiplies your surface area dramatically. Each article can target a different long-tail keyword.
The compound effect is real. A post about "Next.js App Router SEO" might get indexed in week two and receive its first click in month one. By month six it could be driving 50–100 visitors a month to your site — visitors who are specifically interested in the exact thing you know how to build.
Write about problems you've actually solved. "How I fixed a memory leak in a Go service" is infinitely more credible than a generic tutorial. Specificity is what makes technical content rank.
Deployment and Monitoring
I deploy to Vercel via a Git integration. Every push to main triggers a production deploy. Preview deployments on every branch let me verify changes before merging.
For SEO monitoring, I use three free tools:
- Google Search Console — impressions, clicks, average position, and crawl errors.
- Vercel Speed Insights — real-user Core Web Vitals data from actual visitors.
- PageSpeed Insights — lab-based performance audits powered by Lighthouse.
What's Next
This portfolio is a living project. The next things on my list are:
- An Open Graph image generator using
@vercel/og - An RSS feed for the blog
- More articles targeting specific TypeScript and Go keywords
- A case study section for each project with detailed write-ups
If you're building your own developer portfolio, start simple. A clean homepage with good metadata, a projects page, and one well-written blog post will outperform a complex site with no SEO every single time.
Check out my projects to see what I've shipped, or get in touch if you want to collaborate.