Skip to content

Tech Stack

Michel edited this page Mar 29, 2026 · 2 revisions

Tech Stack

Draft v0 is a full-stack TypeScript application. Every technology choice has a rationale — recorded in Architecture Decisions.

Overview

Layer Technology Why
Frontend React 19, TypeScript Stable, widely adopted, React 19 removes legacy APIs (forwardRef, React.FC)
Routing TanStack Router Type-safe file-based routing without Next.js overhead
Data fetching TanStack Query Server state management with caching, invalidation, and background refetching
Design System DSAi + Bootstrap 5.3 Token-driven design system with Figma sync, multi-format output, Bootstrap utility classes
Backend Node.js + Express Minimal and flexible, pairs cleanly with TypeScript
Database Prisma ORM (SQLite) Type-safe queries, easy migrations, SQLite for zero-config dev
Build Vite 6 Fast HMR, ESM-first, handles both client and server builds
Testing Vitest + Playwright Unit tests via Vitest (same API as Jest), e2e via Playwright
Quality Biome + ESLint Biome for fast lint/format, ESLint for additional rules
Forms React Hook Form + Zod Performant forms, Zod schemas shared between client and server
Client state Zustand Minimal, focused stores for UI-only state (modals, sidebar, theme)
Design Figma MCP + Code Connect Direct Figma API access for design-to-code, Dev Mode integration
Security Helmet + express-rate-limit HTTP security headers, API rate limiting out of the box

Frontend

React 19

React 19 removes several legacy APIs that caused confusion and added boilerplate:

  • No forwardRefref is now a regular prop
  • No React.FC — just write function MyComponent(props: Props)
  • No propTypes — TypeScript handles runtime-safety concerns at build time

All components in this project follow React 19 conventions. See Skills Referencereact skill.

TanStack Router

TanStack Router provides full type safety across routes, params, and search params. Key advantages over alternatives:

  • Type-safe useParams(), useSearch(), and Link component
  • File-based routing (src/client/routes/) — no manual route config
  • Works as a pure SPA without a server-side rendering framework

TanStack Query

All server data flows through TanStack Query. Never use useState + useEffect to fetch API data.

// Correct: server data via useQuery
const { data: users } = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/api/users").then((r) => r.json()),
});

// Correct: mutations via useMutation
const mutation = useMutation({
  mutationFn: createUser,
  onSuccess: () => queryClient.invalidateQueries({ queryKey: ["users"] }),
});

DSAi Design System + Bootstrap 5.3

The project uses the DSAi design system for design token management and Bootstrap 5.3 as the utility/component framework. This replaces the previous Tailwind CSS v4 + shadcn/ui setup (see ADR 0014).

Key aspects:

  • Design tokens are structured JSON files in src/collections/ (color, typography, spacing, shadow, border, layout)
  • Token pipeline (pnpm tokens:build) transforms tokens into CSS variables (--dsai-*), SCSS variables, JS/TS constants, and JSON
  • Bootstrap integrationsrc/scss/dsai-theme-bs.scss maps DSAi tokens to Bootstrap 5.3 variables
  • Dark mode via [data-dsai-theme="dark"] attribute and prefers-color-scheme media query
  • Figma syncpnpm figma:sync pulls design tokens directly from Figma

Components use Bootstrap utility classes (btn, container, d-flex, p-4, etc.) and --dsai-* CSS custom properties for design token values.

See DSAi Design System for the full guide and Figma Tokens for the token mapping.

Backend

Express + Layered Architecture

The backend follows a strict 4-layer architecture. Each layer has one responsibility:

Route → Controller → Service → Repository → Prisma (SQLite)
Layer Location Responsibility
Routes src/server/routes/ Map HTTP method + path to controller
Controllers src/server/controllers/ Parse request, call service, send response
Services src/server/services/ Business logic, throw custom errors
Repositories src/server/repositories/ Prisma queries only, no business logic

See Project Structure for the full breakdown.

Prisma ORM

Prisma provides type-safe database access. The schema lives in prisma/schema.prisma. Changes are applied with pnpm db:push (development).

Key rules:

  • Never use raw SQL — use the Prisma Client API
  • Handle P2002 (unique constraint) and P2025 (record not found) explicitly
  • Use import type { User } from "@prisma/client" for model types

Quality & Security

Tool Role
Biome Fast lint and format — replaces ESLint + Prettier for most rules
ESLint Additional rules Biome does not cover
TypeScript strict noImplicitAny, strictNullChecks, noUncheckedIndexedAccess
Helmet Sets Content-Security-Policy, X-Frame-Options, and other security headers
express-rate-limit Protects API routes from abuse and brute-force attacks
Codacy CLI Automated code quality analysis after every file edit

Architecture Decisions for the full decision log · Contributing for quality gates

Clone this wiki locally