- Architecture
- Product systems
- Next.js
- Three.js
Designing a Portfolio as a Product System
How the portfolio separates professional evidence, editorial content, interactive Labs, API safety, and a playful Three.js experience.
- Published
- Updated
- Reading time
- 7 min read

On this page
A portfolio has two jobs: help someone understand the engineer quickly, then provide enough evidence to earn a deeper conversation. Everything else—articles, demos, effects, and an interactive space game—should support that hierarchy rather than compete with it.
This site is a Next.js application with a conventional professional surface, a small Labs area, server-backed demos, and Nebula: a Three.js route through the same public story. The architecture grew over several iterations, including changes that were later simplified or removed.
Give the professional story one clear hierarchy
The homepage is intentionally linear: positioning, selected work, recent experience, operating principles, writing, and contact. It does not try to reproduce the résumé or list every project. Each section answers the next reasonable question and links to a deeper route when more context is useful.
- Case studies carry product constraints, contribution, evidence, and limitations.
- The résumé remains the compact chronological source.
- Writing demonstrates reasoning that cannot fit inside a project summary.
- Labs contains experiments without presenting them as client or employer outcomes.
This separation matters for credibility. A playful demo can show curiosity; it should not blur the distinction between shipped professional work and a personal experiment.
Keep public claims in small typed registries
Repeated profile facts, work entries, and article metadata live in typed modules rather than being rewritten independently on every page. The homepage, work archive, metadata, structured data, sitemap, and Nebula can then reference the same reviewed source.
A registry does not need to become a content platform. For a portfolio of this size, a few TypeScript records are easier to review than a CMS, keep build-time output predictable, and make stale claims testable. Long editorial bodies remain normal server-rendered components because they benefit from explicit markup and links.
Separate experiments from the primary visitor path
The travel planner, sticker generator, and Cosmic Explorer are useful demonstrations, but they depend on external services and have different maintenance expectations from the core portfolio. Labs gives them an honest frame: experimental, bounded, and optional.
Each demo should explain what is live, what may fall back to sample data, what information leaves the browser, and whether an affiliate relationship exists. When a demo cannot be maintained to the same standard, it can remain as a clearly labelled archive without weakening the professional path.
Build Nebula as an extra route, not a required introduction
Nebula maps profile, skills, work, and contact content onto planets and stations. The game owns its renderer, controls, loading state, model assets, audio preferences, and browser-only AI guide. It is deliberately excluded from the fastest path through the portfolio.
This boundary protects both experiences. A recruiter can read case studies without loading Three.js or GLB models; someone who wants the more memorable route can opt in. The game also has procedural fallbacks, but those fallbacks must not hide asset regressions—automated browser tests now verify that the real ship and asteroid models finish loading.
Treat every external integration as a server boundary
Contact email, AI text, travel recommendations, images, and news all pass through server routes. Those routes validate input, apply time and size limits, keep provider credentials off the client, and return product-specific errors rather than raw upstream responses.
- Environment variables are server-only unless the browser genuinely needs the value.
- Remote URLs are allow-listed or validated before the server fetches them.
- Rate limits and bot checks reduce abuse without making the happy path opaque.
- Fallback content is labelled so a visitor can distinguish live data from a sample.
Make quality and maintenance visible in the structure
Metadata and structured data are generated from the same content registries. Unit tests cover those contracts and API boundaries; Playwright covers the main visitor routes and Nebula assets. Accessibility checks focus on semantics and interaction rather than treating a score as proof that the experience works.
Architecture checks, content registries, browser tests, and performance audits keep changes reviewable as the site grows. The maintenance system stays behind the scenes so the public experience can remain focused on the work rather than the tools used to build it.