Shipping a Developer Portfolio
How I used Next.js App Router, Tailwind v4, and shadcn/ui to build a production-ready developer portfolio

"Abstract isometric 3D illustration of stacked application interface layers with modern UI design elements and data visualization on dark background"
Photo by Perplexity Labs
Series: Portfolio
4 posts in this series
Series Background: This is the first post in the Portfolio series. . What started as a minimal portfolio has evolved into a production-ready platform with comprehensive security, featuring CSP headers, rate limiting, Redis analytics, background job processing, and extensive monitoring. This series documents the complete journey from initial build to production deployment.
I wanted to build a focused portfolio that is fast to load, easy to iterate on, and simple to host. After trying a few prototypes, I settled on a modern stack that prioritizes , typed data, and tiny bundles.
Why App Router?
The Next.js represents a fundamental shift toward server-first rendering. Unlike the Pages Router, App Router makes server components the default, which means:
- Better performance: Initial page loads are faster since most components render on the server.
- Improved SEO: Content is fully rendered before it reaches the browser.
- Reduced client bundle: Only interactive components ship JavaScript to the client.
- Streaming and suspense: Built-in support for progressive loading.
In this portfolio, I only use client components where it actually matters, theme toggling, the contact form, and a few sprinkle interactions.
Architecture cheat sheet
src/
├── app/ # App Router pages and API routes
├── components/ # Reusable UI components
├── content/ # MDX blog posts with frontmatter
├── data/ # Typed static data (projects, resume)
└── lib/ # Utilities and helpersStack deep dive
Next.js 15 + React 19
- App Router with server components by default
- for lightning-fast dev server (production builds use Webpack)
- with zero config
TypeScript (strict)
- Type definitions for posts and projects ensure type safety
- Server routes validate payloads aggressively
- Strict mode catches errors at compile time
Tailwind CSS v4
- CSS-first mental model
- Dark mode via CSS variables, no class juggling
shadcn/ui
- Accessible (Dialog, Dropdown, Tooltip, etc.)
- Headless building blocks with
- Copy-paste component library that you own
Deployment
Everything lands on Vercel with zero manual knobs. Analytics and Speed Insights are on by default, headers are set via vercel.json, and the whole thing stays fast.
Content Management
Blog posts live as individual MDX files in src/content/blog/, parsed at build time with for frontmatter. This approach offers:
- Version control: Every post is tracked in Git
- Simple authoring: Write in Markdown with React components
- Type safety: Frontmatter is validated against TypeScript types
- Build-time rendering: Posts are statically generated for speed
MDX content is rendered with and enhanced with rehype plugins for auto-linking headings and GitHub-flavored markdown.
Takeaways
- Server components encourage you to ask “does this need to be interactive?”
- Tailwind v4 wipes away config noise
- File-based content with MDX provides Git-backed authoring
- Type-safe frontmatter catches errors before deployment
Search and tag filtering are now live without compromising the stack’s simplicity, and view counts remain on the roadmap.
What’s Next?
This was just the beginning. After shipping, I spent time hardening the site for production with security improvements, performance optimizations, and developer experience enhancements.
What did you think?
Feel free to send us a message with your thoughts, or learn more about us!
Related Posts
Building Event-Driven Architecture with Inngest
Implement event-driven architecture with Inngest for instant API responses, automatic retries, and production-grade background processing. Real code from a live portfolio.
Hardening a Developer Portfolio
A multi-part series on building production-ready developer platforms: implementing CSP, rate limiting, INP optimization, analytics, and comprehensive security features.
Modernizing Blog Content with RIVET: A Component-Driven Enhancement Framework
Introducing RIVET: a systematic framework for enhancing blog content with 8 interactive components. Real implementation data from 4 blog posts with 181 component instances, 97 passing tests, and measurable engagement improvements.
