shippedDesigner & Developer2025
Portfolio Redesign โ ChatGPT-Style Personal Site
Redesigned personal portfolio with ChatGPT-inspired UI, achieving 95+ Lighthouse scores across all metrics

Problem
My previous portfolio was:
- Generic: Looked like every other developer site with standard templates
- Slow: Bundle size >500KB, LCP >3s on 4G
- Hard to update: Static HTML required manual editing for each project
Goal: Create a distinctive, fast, content-first portfolio that showcases work effectively.
Approach
1. Design Language
Borrowed familiar patterns from ChatGPT's UI:
- Left sidebar navigation with clear hierarchy
- Large center canvas with generous whitespace
- Subtle right rail for featured content
- System fonts for instant loading
2. Content System
Type-safe MDX with Contentlayer:
// Automatic type generation from frontmatter
import { allProjects } from '@/.contentlayer/generated';
const project: Project = allProjects[0];
project.normalizedTags; // โ
Type-safe
project.url; // โ
Computed from filename
3. Performance Budget
- JS bundle: Less than 120KB gzipped on landing
- LCP: Under 1s on 4G
- CLS: Under 0.05
- All pages statically generated at build time
Impact
Performance wins:
- Lighthouse scores: 100/100 (Performance), 100/100 (Accessibility), 98/100 (Best Practices), 100/100 (SEO)
- LCP of 0.6s on 4G (83% improvement)
- 92KB JS bundle (82% reduction)
- Zero CLS
Developer experience:
- Write case studies in MDX with components
- Auto-generated OG images for all pages
- Type-safe content with validation at build time
- Hot reload for instant preview
Business metrics (first 30 days):
- 15% click-through on "Copy Email" CTA
- 28 inbound inquiries from portfolio traffic
- 3 client projects initiated
Technical Highlights
Tag Normalization
// Input: ["AI", "Memory Systems", "OSS"]
// Output: ["ai", "memory-systems", "oss"]
normalizedTags: doc.tags.map(tag =>
tag.toLowerCase().trim().replace(/\s+/g, '-')
)
Computed SEO Fields
ogTitle: doc.seo?.title ?? doc.summary,
ogDescription: doc.seo?.description ?? doc.summary
Build-Time Validation
Invalid frontmatter fails the build:
โ Missing required field: summary
โ Invalid status: "draft" (must be planned|shipped|archived)
Stack
- Framework: Next.js 15 with App Router
- Styling: Tailwind CSS 4
- Content: Contentlayer + MDX
- Code: TypeScript with strict mode
- Deploy: Vercel with preview deployments
Lessons
- Familiar > Novel: Users appreciate recognizable UI patterns
- Type-safety pays off: Contentlayer's validation caught 12+ frontmatter bugs before production
- Performance compounds: Fast sites get shared more, rank better, convert higher
- Content-first: Rich MDX support makes case studies easier to write and maintain