High-Performance Portfolio System
About the Project
The Objective
Most portfolios are static resumes. I wanted to build a living engineering artifact. This site isn't just a showcase; it's a proof-of-concept for how I approach modern web development: strictly typed, content-driven, and obsessively optimized.
My goal was to eliminate the friction between content creation and deployment. By treating my projects as data (MDX) rather than hard-coded pages, I created a system that scales with my career without requiring refactors.

Architectural Decisions
I avoided boilerplate starters to ensure every line of code served a purpose. The architecture prioritizes Server Components for performance and Type Safety for maintainability.
1. Content as Data (MDX Pipeline)
Instead of a heavy CMS, I built a lightweight file-based system using gray-matter and fs.
- Why: Reduces external dependencies and attack surface.
- Implementation: Project metadata is parsed at build time into TypeScript interfaces. If a project file misses a required field (e.g.,
startDate), the build fails. This enforces data integrity without runtime checks.
2. Next.js 16 App Router & Turbopack
- Server-First Rendering: All project data is fetched server-side. The client receives hydrated HTML, ensuring zero FOUC (Flash of Unstyled Content) and optimal SEO.
- Turbopack: Leveraged for instantaneous HMR during development, significantly improving my own DX while iterating on UI components.
3. Design System (Tailwind CSS v4)
- Token-Driven: Used CSS variables for theming (
--background,--primary) to enable seamless dark/light mode switching without class proliferation. - Utility-First: Avoided custom CSS files. Styling is co-located with logic, making component removal safe and cleanup trivial.
Performance & Accessibility
A pretty site that loads slowly is a failed engineering project. I treated performance as a feature, not an afterthought.
| Metric | Score | Optimization Strategy |
|---|---|---|
| Lighthouse | 100 | Minimal JS bundle, deferred non-critical scripts. |
| FCP | 0.8s | Server-side rendering + font optimization (next/font). |
| Accessibility | 100 | Semantic HTML5, ARIA labels on interactive elements, contrast ratio compliance. |
| SEO | 100 | Dynamic Open Graph images, structured metadata per route. |
Key Engineering Challenges
1. Type-Safe Content Management
Challenge: Ensuring MDX frontmatter matches the TypeScript Project interface without runtime errors.
Solution: Created a strict readProjectFile utility in lib/projects.ts. It validates existence and structure during the build process, catching content errors before deployment.
2. Image Optimization Pipeline
Challenge: High-resolution project screenshots slowing down initial load.
Solution: Implemented next/image with explicit sizes props and modern formats (AVIF/WebP). Lazy loading is enabled for below-the-fold content, preserving bandwidth for critical path elements.
3. Theme Persistence Without Flicker
Challenge: System theme detection often causes a flash of light mode before dark mode loads.
Solution: Implemented a ThemeProvider that reads preference from localStorage and system media queries synchronously during the initial render phase.
Reflections & Iteration
Building this taught me that constraints drive creativity. Limiting myself to standard web APIs instead of heavy libraries forced me to understand the platform deeper.
- What Worked: The MDX approach is sustainable. Adding a new project takes 5 minutes (write file, commit, deploy).
- What I'd Improve: I plan to introduce
unstable_cachefor project data fetching to reduce build times as the project count grows into the dozens.