Building a High-Performance Portfolio with Next.js 16
Building a portfolio website is more than just showcasing your work—it's an opportunity to demonstrate your technical expertise and attention to detail. In this post, I'll walk through the key decisions and architecture behind this portfolio.
Tech Stack
This portfolio is built with cutting-edge technologies:
- Next.js 16 with App Router for optimal performance
- React 19 with Server Components by default
- TypeScript for type safety
- Tailwind CSS v4 for modern, efficient styling
- Turborepo for monorepo management
Performance First
Performance was a top priority from the beginning. Here's how we achieved it:
Server Components
By defaulting to Server Components, we minimize JavaScript sent to the client. Only interactive components like the navigation menu and contact form use client-side JavaScript.
// Server Component (default)
export function Projects() {
return (
<section>
{/* Rendered on the server */}
</section>
)
}
// Client Component (only when needed)
"use client"
export function ContactForm() {
const [formData, setFormData] = useState({})
// Interactive logic here
}
Image Optimization
All images use Next.js's built-in Image component with proper sizing and lazy loading:
<Image
src={project.image}
alt={project.title}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
Static Generation
The entire site is statically generated at build time, resulting in instant page loads and zero server processing for each request.
Accessibility
Accessibility is not an afterthought—it's built into every component:
- Semantic HTML (
<nav>,<main>,<article>) - Proper heading hierarchy
- ARIA labels for icon buttons
- Keyboard navigation support
- Color contrast ratios ≥4.5:1 (WCAG AA)
prefers-reduced-motionsupport
Clean Architecture
The codebase follows a clear separation of concerns:
apps/web/src/
├── components/
│ ├── sections/ # Page sections
│ ├── ui/ # Reusable UI components
│ └── mdx/ # MDX-specific components
├── content/ # Data and MDX files
├── lib/ # Utilities
└── types/ # TypeScript definitions
Monorepo Benefits
Using Turborepo allows us to share UI components across potential future apps:
@repo/ui- Shared component library@repo/typescript-config- Shared TypeScript configs@repo/config- Shared ESLint configuration
Results
The final result speaks for itself:
- Lighthouse Performance: 95+
- First Contentful Paint: < 1.5s
- Time to Interactive: < 2.5s
- Bundle Size: < 150KB (excluding images)
Key Takeaways
- Server Components are powerful - Use them by default
- Performance matters - Users notice slow sites
- Accessibility is essential - Build it in from the start
- Clean architecture - Makes maintenance easier
- Monorepos scale well - Plan for the future
Building this portfolio was an exercise in applying best practices and modern web standards. The result is a fast, accessible, and maintainable website that showcases both content and technical skill.
Want to build something similar? Feel free to reach out or check the source code on GitHub!