Projects/Personal Site/Architecture Decisions

ADR 002: React

Context

I need a UI library to build the user interface for my personal site. My vision for this platform extends beyond a simple static blog; it is intended to be an incubator for future SaaS projects, a testing ground for new technologies, and a showcase of "engineering thinking" (see Context).

My previous site (fastpages) relied on Jekyll templates. This "document-based" approach, while simple, became limiting when I wanted to build richer, interactive components like data visualizations, dashboards, or complex forms.

I need a solution that moves beyond simple templating to a true component-based architecture.

My options include:

  • Vanilla HTML/JS: The "simplest" approach. Low initial complexity, but complexity grows quadratically with size. Lacks a standard component model, making reuse difficult. State management becomes a manual exercise in DOM manipulation
  • Static Site Generators (Jekyll, Hugo): Excellent for text-heavy content, but adding interactivity requires "sprinkling" jQuery or Vanilla JS, leading to a fragmented codebase ("spaghetti code")
  • Modern Component Frameworks (Vue, Svelte, Angular, Solid):
    • Angular: Highly opinionated and heavy. targeted at large enterprise teams. Overkill for a personal site
    • Svelte/Vue: Excellent ergonomics and often smaller bundle sizes. However, they rely on custom template syntax (v-if, {#if}) rather than JavaScript control flow

I want a library that:

  • Is the Industry Standard: I want to use the tool that has won the market, ensuring long-term maintenance and skill transferability
  • Maximizes Leverage: I want access to the largest ecosystem of high-quality, pre-built components (e.g., charts, calendars, animations) so I can focus on unique value, not re-inventing the wheel
  • Is "AI-Native": I want the tool that LLMs are most proficient at writing, debugging, and explaining
  • Scales Up: A solution that works for a blog post but can seamlessly scale to a complex SaaS dashboard without a rewrite
  • Aligns Professionally: I want to refine the skills that are most valuable in the current job market

Decision

I decided to use React.

This aligns with the Choose Boring Technologies principle. React is the web's "standard library" for UI.

  • vs Vanilla JS: React provides the declarative model and component boundaries required for complex applications. The "overhead" of the runtime is paid back in maintainability once the application exceeds trivial complexity
  • vs Svelte/Vue: While Svelte/Vue have passionate communities and often superior ergonomics for small projects, React's ecosystem dominance is the deciding factor. The probability that a library I need exists for React is significantly higher than for any other framework
  • vs Angular: React's "Just JavaScript" (mostly) philosophy aligns better with my preference for composable primitives over rigid framework conventions

Consequences

Pros

  • The Ecosystem: This is the primary advantage. Libraries like framer-motion (animations), tanstack-query (data fetching), shadcn/ui (accessible components), and recharts (visualization) are best-in-class and React-first
  • Mental Model: React's unidirectional data flow and "UI as a function of state" ($UI = f(state)$) is a powerful mental model that reduces bugs compared to two-way binding or manual DOM manipulation
  • Meta-Framework Support: React powers the most advanced meta-frameworks like Next.js and Remix, which solve the hard problems of routing, SSR, and data loading
  • AI Velocity: Because React is the most popular framework, it is the highest-represented language in LLM training sets. Models like Claude and GPT are exceptionally good at writing React, making them more effective "pair programmers" than with niche frameworks
  • Hireability: React is a ubiquitous skill in the industry

Cons

  • Complexity Creep: React requires a build step (bundlers, transpilers) and introduces concepts like useEffect and useMemo specifically to handle its own rendering model. This is incidental complexity that doesn't exist in Vanilla JS
  • "Use Client" Friction: In the modern Next.js Era (RSC), there is friction between Server Components and Client Components, requiring explicit opt-ins ('use client') for interactivity
  • Bundle Size: React includes a runtime overhead. For a purely static blog, shipping the React runtime is technically inefficient compared to Svelte or Vanilla JS, but accepted as the cost of the platform capabilities