Skip to content

Architecture Overview

dagustin415 edited this page Feb 12, 2026 · 4 revisions

Architecture Overview

System Design

Coding Drills is a client-heavy SPA with static generation where possible. There is no database β€” all content is static TypeScript data, all user state lives in localStorage, and AI features run locally via WebGPU.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Presentation Layer                  β”‚
β”‚   Next.js App Router β”‚ React 19 β”‚ Tailwind CSS 4    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                     Data Layer                       β”‚
β”‚  Static TypeScript modules (problems, exercises,     β”‚
β”‚  quizzes, methods, cheatsheets, UI patterns)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                    State Layer                        β”‚
β”‚  React Context (Theme, Progress) β”‚ Custom Hooks      β”‚
β”‚  localStorage persistence β”‚ useSyncExternalStore     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                  Execution Layer                      β”‚
β”‚  In-browser JS/TS runner β”‚ Pattern validation         β”‚
β”‚  API route for TS transpilation                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                     AI Layer                         β”‚
β”‚  WebLLM (Llama-3.1-8B local) β”‚ OpenAI (cloud opt.)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Design Decisions

1. No Database

All state is client-side localStorage. This means:

  • Zero server costs
  • Complete user privacy
  • Instant data access
  • No cross-device sync (tradeoff)

2. Static Data as TypeScript Constants

All problems, exercises, quizzes, and reference content are defined as typed TypeScript constants in /lib/. Benefits:

  • Full type safety at compile time
  • Zero-latency data access
  • Easy to validate with TypeScript compiler
  • Tradeoff: content changes require code changes and redeploy

3. Local-First AI

WebLLM runs Llama-3.1-8B-Instruct locally via WebGPU (~3GB first download, cached after). No API keys needed. OpenAI is an optional cloud fallback.

4. Aggressive Code Splitting

100+ visualization components are individually lazy-loaded via next/dynamic. Monaco Editor is also dynamically imported. Initial bundle stays small.

5. Static Generation

generateStaticParams() pre-renders all 25 language pages and 4 framework pages at build time for fast initial loads.

Project Structure

coding-drills/
β”œβ”€β”€ app/                    # Next.js App Router pages
β”‚   β”œβ”€β”€ [language]/         # Per-language routes (25 languages)
β”‚   β”œβ”€β”€ frontend-drills/    # Frontend framework routes (4 frameworks)
β”‚   β”œβ”€β”€ interview/          # AI mock interview
β”‚   β”œβ”€β”€ regex/              # Regex trainer
β”‚   β”œβ”€β”€ pattern-quiz/       # Algorithm pattern quiz
β”‚   β”œβ”€β”€ links/              # External links
β”‚   └── api/transpile/      # TypeScript transpilation endpoint
β”œβ”€β”€ components/             # React components
β”‚   β”œβ”€β”€ visualizations/     # 100+ algorithm visualizations
β”‚   └── navigation/         # Nav components
β”œβ”€β”€ hooks/                  # Custom React hooks
β”œβ”€β”€ lib/                    # Business logic & data
β”‚   β”œβ”€β”€ problems/           # 25 language problem sets
β”‚   β”œβ”€β”€ exercises/          # Building Blocks exercises
β”‚   β”œβ”€β”€ methods/            # Method reference data
β”‚   β”œβ”€β”€ cheatsheets/        # 25 language cheatsheets
β”‚   β”œβ”€β”€ frontend-drills/    # Frontend drill system
β”‚   β”œβ”€β”€ regexTrainer/       # Regex trainer engine
β”‚   β”œβ”€β”€ interview/          # AI interview system
β”‚   β”œβ”€β”€ core/               # Shared types & constants
β”‚   └── services/           # Storage adapters
β”œβ”€β”€ e2e/                    # Playwright E2E tests
β”œβ”€β”€ stories/                # Storybook stories
└── scripts/                # Build & generation scripts

Dependency Flow

app/ pages ──→ components/ (UI rendering)
     β”‚
     β”œβ”€β”€β†’ lib/ (data + business logic)
     β”‚
     └──→ hooks/ (state management)
              β”‚
              └──→ lib/storage (localStorage persistence)

components/ProgressProvider ──→ localStorage
components/ThemeProvider ──→ localStorage
lib/codeValidator ──→ lib/codeRunner (JS/TS execution)
components/visualizations/ ──→ next/dynamic (lazy loading)

SSR/CSR Split

Component Type Rendering Examples
Layouts Server Component [language]/layout.tsx, [framework]/layout.tsx
Metadata Server generateMetadata() in layouts
Static params Build time generateStaticParams() for languages/frameworks
Interactive pages Client ('use client') Drill, Quiz, Exercise, UI Pattern detail pages
Monaco Editor Client (dynamic import) { ssr: false }
Visualizations Client (dynamic import) { ssr: false } via registry

Clone this wiki locally