Skip to content
ermalbujupaj.dev
All posts

Jul 11, 2026 · 2 min read · Meta

Why this site exists (and how it's built)

The thinking behind ermalbujupaj.dev: a monorepo platform, a two-line re-brand, and phases that ship like production software.

Most personal sites are built once and then quietly rot. They start as a template, get customized for a weekend, and two years later the "recent projects" section is a museum. I wanted something different: a personal platform with the properties I demand from production software — one brand, one design system, and room to grow for a decade.

The platform bet

This site is a Turborepo monorepo where the portfolio is just the first app. Future side projects ship as sibling apps on subdomains — each independently deployable, all sharing one design language through a single package, @ermal/ui.

The design system is deliberately small. The entire visual identity — every button, link, focus ring and selection highlight — derives from one CSS variable:

/* packages/ui/src/styles/globals.css */
:root {
  --brand: oklch(0.51 0.23 262);
}
 
.dark {
  --brand: oklch(0.62 0.21 262);
}

Change those two lines and every app, current and future, re-brands. That's not a party trick; it's the difference between a design system and a pile of styles.

Server Components as a budget

The whole site is React Server Components by default. A component only gets "use client" when it has a reason — state, effects, browser APIs. Right now a handful of components hydrate: the theme toggle, the mobile menu, two interactive sections, and the animation wrappers. Everything else is static HTML.

The interesting part is that shared packages don't need a build step for this to work:

// apps/web/next.config.ts
const nextConfig: NextConfig = {
  // @ermal/ui ships raw TypeScript — the app compiles it
  // together with its own code and tree-shakes the rest.
  transpilePackages: ["@ermal/ui"],
  typedRoutes: true,
};

Phases, not sprints to nowhere

The site ships in strictly-scoped phases — foundation, hero, skills, experience, projects, this blog — each one built, verified in a real browser, and reviewed before the next begins. The discipline caught real bugs a green build never would have: a scroll lock silently swallowing anchor navigation, a pre-commit hook that couldn't find its own linter.

That's the actual thesis of this site. Anyone can ship a portfolio. Shipping one the way you'd ship a product is the part worth writing about — and that's what this blog is for.

  • #nextjs
  • #architecture
  • #design-systems