Skip to content
All workCase study · 2026

A server-rendered portfolio with its own CMS, live activity data, and a three.js house you can walk through, room by room.

Next.jsTypeScriptPostgreSQLDrizzlethree.jsTailwind
100Lighthouse desktop, all four
ROLE
Solo build
TIMEFRAME
2026
STACK
Next.js, TypeScript, PostgreSQL, Drizzle, three.js, Tailwind

100

Lighthouse desktop, all four

The problem

The June 2026 rebuild replaced a JavaScript-only single-page portfolio (one that shipped an empty HTML shell, so crawlers, link previews, and anyone on a slow connection saw a blank page while the bundle loaded) with a server-rendered site, its own CMS, and a hero built from real commit data. That was the "Signal" design, and its signature was an SVG line chart of 52 weeks of commits.

By September it was fast and honest, but not memorable: it read like a well-made template. The goal of this round was to make it unmistakably mine without giving back any of the speed.

Approach

Terrain → House: the second round replaced the point-cloud landscape with a small three.js house, an architect's maquette lit like a model on a table, and turned navigation itself into the metaphor. Each page is a room, reached by walking through a door; projects hang as paintings in a gallery; the same year of GitHub commits that once drew a heightmap is now a contour model on a plinth in the hall, cut into layers like a survey map. Every room's geometry is its own dynamically imported chunk, so a visit fetches the room it walks into and nothing else, and the classic look, still a plain server-rendered page underneath, ships none of it: no fine pointer, a narrow viewport, reduced motion, low memory, or data-saver all fall back to classic, a stored preference and the toggle in the nav always win, and a house that starts dropping frames turns its own quality down before it turns itself off. Scrolling runs through Lenis; walking between rooms never touches the browser's View Transitions API, which the classic look still uses on its own. Everything is server-rendered Next.js 15 on PostgreSQL through Drizzle, behind a small admin CMS I built myself, so editing a project or a note is a form submit, not a redeploy, and the whole thing, three.js included, runs on Render's 512MB free tier behind Cloudflare.

Results

Measured on the live deploy: Lighthouse desktop scores 100 across Performance, Accessibility, Best Practices, and SEO, with an LCP of 0.4s and zero CLS. Mobile comes in at 97/100/100/100, with LCP at 2.3s.

One decision I'd defend: splitting the house per room instead of shipping one bundle for all seven. three.js has a real floor, on the order of 140KB gzipped no matter how little of it you use, and no amount of hand-written discipline gets under that once it is the renderer; the fix was never to avoid the cost but to make sure a visit only pays it once and only fetches the one room it is standing in. One decision I'd revisit: mobile stays on the classic look entirely for now, so the house itself has only ever been measured on desktop.

This website · Aditya Ravi