Skip to content
nextjsportfolio3dr3ftypescript

Building This Portfolio

Basil Francis Alajid
March 25, 2026
7 min read (1,550 words)β€”

Building This Portfolio

Problem

Most developer portfolios are forgettable. A hero section with a name, a grid of project cards, a contact form. They demonstrate nothing about the builder except that they can follow a template. I wanted mine to be a technical artifact itself β€” something worth inspecting.

The average portfolio tells a recruiter "I exist." It does not tell another engineer "I think carefully about the systems I build." I set out to make a site that would hold up under technical scrutiny β€” where the source code is as much a portfolio piece as the content it renders.

Constraints

Five rules governed every decision:

  1. Must run on mid-range Android phones. Not just MacBook demos at coffee shops. If the 3D hero drops below 30fps on a Pixel 6a, it ships broken for half the world. Every visual flourish had to earn its frame budget.

  2. Zero external binary assets. No Spline scenes. No Blender exports. No opaque binaries that I cannot inspect, modify, or optimize at the code level. Every vertex is authored in TypeScript.

  3. Accessible. Screen readers get the same information through a different channel. The 3D canvas is not the content β€” it is decoration. The real content lives in semantic HTML underneath.

  4. AI assistant must be genuinely useful. Not a chatbot gimmick that answers "tell me about yourself" and nothing else. It needed to search projects, pull GitHub stats, answer technical questions about the stack, and do most of it at zero API cost.

  5. Ship fast, iterate in public. The constellation launched with 7 stars. The AI assistant launched with 10 hardcoded answers. Perfection is the enemy of a deployed portfolio.

System

The portfolio is built on Next.js 14 (App Router), TypeScript, Tailwind CSS, Framer Motion, and React Three Fiber for 3D. Four systems carry the weight.

3D Constellation Hero

Eleven procedural celestial objects, each representing a technology in my stack. The mapping is deliberate:

  • TypeScript is the Black Hole β€” a dark core with spinning blue accretion disks. Gravitational center of the entire stack. Everything orbits it.
  • React is the Ringed Planet β€” a solid sphere with two tilted torus rings. Stable core, rich ecosystem orbiting around it.
  • Node.js is the Spiral Galaxy β€” 2000 particles arranged in three logarithmic arms. Massive, sprawling, everywhere you look.
  • PostgreSQL is the Binary Star β€” two spheres in mutual orbit. Reads and writes, forever circling each other.
  • Playwright is the Pulsar β€” spinning cone beams sweeping at 2 radians per second. Precise, rhythmic, relentless coverage.
  • Docker is the Gas Giant β€” banded sphere with an atmospheric torus ring. Layers upon layers of configuration.
  • Rust is the Star β€” copper glow with layered halos. Raw power, compact, blazing.
  • Python is the Nebula β€” a soft gas cloud built from 10 transparent puffs. Diffuse, everywhere, shapes everything around it.
  • React Native is the Comet β€” bright head with a coma, drifting in an orbiting path. Born from the same material as its parent, traveling its own trajectory.
  • Git is the White Dwarf β€” tiny, intense, flickering. Small footprint, enormous density, quietly holding everything together.
  • Three.js/R3F is the Planetary Nebula β€” colorful rotating rings. The rendering layer that makes the rest visible.

Zero textures. Zero imported models. Fifteen kilobytes of procedural geometry code replacing a 263KB Spline binary blob.

The Spline keyboard was the first attempt. It was a 3D interactive keyboard loaded via @splinetool/react-spline. It looked impressive in screenshots. It broke on mobile. It could not be inspected or modified without opening a separate design tool. It outsourced the most visible part of the portfolio to a dependency I did not control and could not optimize. I deleted it. That deletion was one of the best decisions in this project.

AI Chat Assistant

Claude-powered with a tiered context injection system. The architecture has three layers:

Tier 1 loads on every request β€” site structure, author info, core capabilities. Tier 2 loads conditionally based on the question topic β€” project details, blog content, technical depth. Tier 3 is on-demand tool calls β€” searching projects, querying GitHub stats, checking availability.

Over 80 question patterns are handled by hardcoded instant answers at zero API cost. "What's your tech stack?" does not need a language model. It needs a lookup table. The AI only fires for genuinely complex or conversational queries.

The tool system supports search_projects, search_blogs, get_github_stats, check_availability, and get_project_detail. Jailbreak detection catches prompt injection attempts. Redis backs conversation memory across sessions. Rate limiting caps usage at 20 requests per hour.

This is not a chatbot widget. It is a knowledge base with a conversational interface.

Blog System

MDX with TF-IDF search that includes synonym expansion, tag filtering, series support, per-post reactions, RSS feed generation, and newsletter integration. Two categories: Engineering and Personal. The search is surprisingly capable β€” querying "database" returns posts about PostgreSQL, Redis, and SQL even if the word "database" never appears in the title.

Performance Architecture

Every homepage section is dynamically imported with explicit height placeholders to prevent layout shift. The constellation loads with ssr: false β€” there is no server-side rendering of WebGL. Particles run at a 30fps cap and pause entirely when the browser tab is hidden or the canvas scrolls offscreen, detected via IntersectionObserver.

Mobile devices get aggressive degradation: 3800 particles drop to 1000. Bloom postprocessing is disabled. Antialiasing is off. Device pixel ratio is capped at 1x. Sphere segment counts drop from 32 to 16. A shared texture singleton prevents duplicate GPU allocations between particle systems.

Execution

The details that made it work:

Constellation metaphors are load-bearing, not decorative. Every star-to-technology mapping encodes something true about the technology. PostgreSQL as a binary star is not clever wordplay β€” it reflects the fundamental read/write duality. Playwright as a pulsar reflects the sweeping, rhythmic nature of test suites. If the metaphor does not teach something, it does not belong.

Mobile optimization is not optional polish. GPU tier detection runs on first load. Based on the result, the constellation adjusts particle counts, geometry complexity, and postprocessing. This is not graceful degradation β€” it is a completely different render path for constrained devices.

Accessibility is a parallel system, not an afterthought. The entire R3F canvas is wrapped in aria-hidden="true". The skills section grid β€” plain HTML, fully semantic β€” is the accessible version of the constellation. MotionConfig in the providers respects prefers-reduced-motion globally. Every Framer Motion animation checks this before running.

Security is not just for production apps. CSP headers restrict connect-src to specific domains. Origin validation runs on every POST route. All API inputs pass through Zod schemas. The AI chat route validates session tokens and blocks cross-origin requests. A portfolio with an AI endpoint is an attack surface whether you like it or not.

SEO is structural. JSON-LD structured data on every page type β€” Person and WebSite on root, BlogPosting on articles, FAQPage on the interview section. Dynamic OG images generated per blog post and project. RSS feed at /feed.xml. Canonical URLs prevent duplicate content indexing.

Outcome

The numbers that matter:

  • 66 pages across the site β€” blog posts, projects, case studies, admin dashboards
  • 46 tests passing covering API routes, component rendering, and AI tool execution
  • Sub-200ms to first 3D frame after dynamic import completes
  • 80+ question patterns handled at zero API cost by the hardcoded answer system
  • Full accessibility audit passing β€” no WCAG AA violations
  • Lighthouse Performance 90+ despite shipping a WebGL scene on the homepage

Lessons

Over-engineering a portfolio is worth it if you treat it as a learning platform. This project taught me React Three Fiber, procedural geometry, Redis caching patterns, SSE streaming, and TF-IDF search implementation. Every one of those skills transferred directly to production work within months. The portfolio was not a vanity project β€” it was a structured learning environment with a deployment deadline.

Own your dependencies or they own you. The Spline keyboard looked great until I needed to optimize it, debug it on mobile, or modify it without opening a completely separate application. Replacing it with 15KB of procedural TypeScript gave me full control over every vertex, every animation frame, every performance tradeoff. The binary blob is always the wrong choice for your most visible component.

Ship before it is done. The constellation launched with 7 stars and grew to 11 through iteration. The AI assistant started with 10 hardcoded answers and now has over 80. The blog launched with 3 posts. If I had waited for "complete," none of it would be deployed. A portfolio that exists beats a portfolio that is perfect in a private repository.

Build for engineers, not recruiters. A portfolio that impresses other engineers is more valuable than one that impresses recruiters. Engineers refer engineers. A recruiter sees a nice website. An engineer opens DevTools, reads the source, and decides whether you think clearly about the systems you build. Optimize for the second audience.

Performance constraints produce better designs. Forcing the constellation to run on mid-range phones eliminated every lazy decision. No massive textures. No unoptimized particle counts. No "it works on my machine" postprocessing. The constraints did not limit the design β€” they sharpened it. The procedural approach is more interesting than a pre-built model precisely because it had to be lightweight.

0
0
0
0
0

Share

Enjoyed this post?

Follow along for more engineering deep dives and project breakdowns.

No spam, ever.

|RSS

Comments

Comments coming soon.

You found the bottom! 🎯