Build a Modern Portfolio with Next.js 15
Build a stunning Next.js 15 portfolio with TypeScript, Tailwind CSS, dark mode, and animations. Achieve 98+ Lighthouse scores—complete guide inside.
Creating a professional portfolio website is crucial for any developer looking to showcase their skills and attract potential clients or employers. In this comprehensive guide, I'll walk you through building a modern, high-performance portfolio using the latest web technologies.
Why Next.js 15?
Next.js 15 introduces several compelling features that make it an excellent choice for portfolio websites. For those interested in serverless deployments, check out my guide on building serverless React applications which covers many of the architectural patterns that make Next.js ideal for modern web apps.
- App Router: The new App Router provides a more intuitive file-based routing system
- Server Components: Improved performance with server-side rendering by default
- TypeScript Integration: First-class TypeScript support out of the box
- Optimized Bundle: Smaller bundle sizes and faster loading times
- SEO Friendly: Built-in optimization for search engines
Project Architecture
Tech Stack Overview
const techStack = {
framework: "Next.js 15",
language: "TypeScript",
styling: "Tailwind CSS",
animations: "CSS + Intersection Observer",
deployment: "Vercel",
performance: "Lighthouse Score 95+"
};
Directory Structure
portfolio/
├── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── globals.css
│ ├── components/
│ │ ├── Hero.tsx
│ │ ├── Navigation.tsx
│ │ ├── Projects.tsx
│ │ └── Contact.tsx
│ ├── hooks/
│ │ ├── useScrollReveal.ts
│ │ └── useCountUp.ts
│ └── contexts/
│ └── ThemeContext.tsx
├── public/
│ ├── projects/
│ └── resume.pdf
└── package.json
Key Features Implementation
1. Responsive Navigation
The navigation component adapts to different screen sizes and provides smooth scrolling:
'use client';
import { useState, useEffect } from 'react';
export default function Navigation() {
const [isScrolled, setIsScrolled] = useState(false);
const [activeSection, setActiveSection] = useState('hero');
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 50);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return (
<nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
isScrolled ? 'bg-white/80 backdrop-blur-md shadow-lg' : 'bg-transparent'
}`}>
{/* Navigation content */}
</nav>
);
}
2. Dark Mode Implementation
Using React Context for theme management. For a detailed implementation guide, see my article on implementing dark mode with Tailwind CSS:
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
type Theme = 'light' | 'dark' | 'system';
interface ThemeContextType {
theme: Theme;
setTheme: (theme: Theme) => void;
resolvedTheme: 'light' | 'dark';
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<Theme>('system');
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light');
useEffect(() => {
const root = window.document.documentElement;
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
setResolvedTheme(systemTheme);
root.classList.toggle('dark', systemTheme === 'dark');
} else {
setResolvedTheme(theme);
root.classList.toggle('dark', theme === 'dark');
}
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, setTheme, resolvedTheme }}>
{children}
</ThemeContext.Provider>
);
}
3. Scroll Reveal Animations
Custom hook for intersection observer animations:
import { useEffect, useRef } from 'react';
export function useScrollReveal(threshold = 0.1, delay = 0) {
const elementRef = useRef<HTMLElement>(null);
useEffect(() => {
const element = elementRef.current;
if (!element) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setTimeout(() => {
element.classList.add('animate-fadeInUp');
}, delay);
observer.unobserve(element);
}
},
{ threshold }
);
observer.observe(element);
return () => observer.disconnect();
}, [threshold, delay]);
return elementRef;
}
Performance Optimization
Image Optimization
Using Next.js Image component for optimal performance:
import Image from 'next/image';
export default function ProjectCard({ project }: { project: Project }) {
return (
<div className="project-card">
<Image
src={project.image}
alt={`${project.title} screenshot`}
width={600}
height={400}
className="w-full h-48 object-cover"
priority={project.featured}
/>
</div>
);
}
Bundle Analysis
Monitor bundle size and optimize imports:
npm install --save-dev @next/bundle-analyzer
# In next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// Next.js config
});
SEO and Meta Tags
Implement proper meta tags for better search engine optimization:
// app/layout.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Richard Joseph Porter | Full-Stack Developer',
description: 'Experienced full-stack developer specializing in modern web technologies...',
keywords: ['developer', 'portfolio', 'next.js', 'typescript'],
authors: [{ name: 'Richard Joseph Porter' }],
openGraph: {
title: 'Richard Joseph Porter | Full-Stack Developer',
description: 'Experienced full-stack developer specializing in modern web technologies...',
url: 'https://richardporter.dev',
siteName: 'Richard Joseph Porter',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
},
],
locale: 'en_US',
type: 'website',
},
};
Deployment and Performance
Vercel Deployment
Deploying Next.js to Vercel provides excellent performance and seamless integration. For cost optimization strategies, you might also want to explore AWS cost optimization for PHP and Laravel apps which includes relevant infrastructure considerations.
- Connect your GitHub repository to Vercel
- Configure build settings:
{
"buildCommand": "npm run build",
"outputDirectory": ".next",
"framework": "nextjs"
}
Performance Monitoring
Track Core Web Vitals:
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Analytics />
</body>
</html>
);
}
Results and Metrics
After implementing these optimizations, the portfolio achieves:
- Lighthouse Performance: 98/100
- First Contentful Paint: <1.5s
- Largest Contentful Paint: <2.5s
- Cumulative Layout Shift: <0.1
- Bundle Size: <200KB initial load
Conclusion
Building a modern portfolio with Next.js 15 provides an excellent foundation for showcasing your work while demonstrating your technical skills. The combination of TypeScript, Tailwind CSS, and thoughtful performance optimizations creates a professional, fast-loading website that stands out to potential clients and employers.
Once your portfolio is built, consider extending it with additional features like a blog system for sharing your insights and a secure contact form for client inquiries.
Key takeaways:
- Performance First: Optimize images, minimize bundle size, and leverage Next.js built-in optimizations
- User Experience: Implement smooth animations and responsive design
- SEO Optimization: Use proper meta tags and structured data
- Modern Stack: Stay current with the latest web technologies
- Accessibility: Ensure your portfolio is accessible to all users
The modern web development landscape offers incredible tools for creating impressive portfolio websites. By leveraging Next.js 15's capabilities and following best practices, you can build a portfolio that not only showcases your projects but also demonstrates your commitment to quality and performance.

Richard Joseph Porter
Senior Laravel Developer with 14+ years of experience building scalable web applications. Specializing in PHP, Laravel, Vue.js, and AWS cloud infrastructure. Based in Cebu, Philippines, I help businesses modernize legacy systems and build high-performance APIs.
Looking for Expert Web Development?
With 14+ years of experience in Laravel, AWS, and modern web technologies, I help businesses build and scale their applications.
Related Articles
React Server Components & Serverless: 2025 Guide
Master React Server Components with serverless architecture. Achieve 60% faster cold starts, 40% cost savings, and improved Core Web Vitals.
Build a Markdown Blog with Next.js and SSG
Build a lightning-fast Next.js 15 blog with markdown, SSG, and dark mode. Complete guide from setup to deployment with excellent Core Web Vitals.
Migrate WordPress to Laravel: The Complete Developer Guide
Step-by-step guide to migrating WordPress sites to Laravel. Cover content migration, database design, SEO preservation, and custom feature implementation.