# ADR-0001 — Toolchain (Vite + pnpm + React 18 + strict TypeScript) - Status: accepted - Date: 2026-05-24 - Workplan: CE-WP-0001-T01 ## Context `citation-evidence` is the umbrella repo for an MVP that will eventually be segmented into six packages (`shared/engine`, `anchor`, `source`, `binder`, `work`, `app` per `wiki/DependencyMap.md`). We need a single toolchain that: 1. Gives a fast inner dev loop for a React-based reference workspace. 2. Plays well with a future pnpm workspace split (so each `src//` folder can become a workspace package with a `git mv` and a `package.json` cut). 3. Provides first-class TypeScript with the strictest practical settings — the shared contracts in `wiki/SharedContracts.md` only pay off if the type system actually enforces them. 4. Has a credible unit-test story for the engine/anchor/source pure-logic code and an integration path for the UI later. ## Options considered - **Vite + pnpm + React + Vitest** *(chosen)* - Fast HMR; well-supported React plugin; Vitest shares the Vite pipeline so tests use the same module resolution as the app. - pnpm workspaces are the most ergonomic path to the eventual multi-package split. - React 18 because the PRD's reference workspace is a desktop-class web app and the ecosystem (PDF viewer libraries, drag-and-drop, etc.) targets it. - **Next.js (App Router)** - Heavier than needed for a local-first reference workspace; SSR/route handlers add complexity the MVP doesn't use. - Harder to split into independent packages later. - **tsc-only + custom runner** - Simplest, but no HMR and we'd hand-roll the React + bundler integration. Pointless overhead for a UI-centric project. - **Bun / Deno** - Toolchain bets that would add risk to the PDF/viewer integration spike, which is already the highest-risk part of the project (see `CE-WP-0002-T02`). ## Decision Use **Vite 5** + **pnpm 9** + **React 18** + **TypeScript 5 with `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `noImplicitOverride`, `noFallthroughCasesInSwitch`, `verbatimModuleSyntax`** turned on. Use **Vitest 2** as the test runner. Node version pinned to **20.10.0 LTS** via `.nvmrc`. Path aliases (`@shared/*`, `@engine/*`, etc.) map to `src//*` so import sites read the same whether or not the folder is later extracted. ## Consequences - Bumping React or Node is a deliberate, ADR-worthy change. - The eventual pnpm workspace split keeps the same import names — each package's `name` becomes `@citation-evidence/` and the path aliases are replaced by package resolution. No source-code churn required. - Vitest's Vite-aware resolution means a contract test that imports across partitions will fail at the same boundary that production code would — there is no test-only loophole. - ESLint rules enforcing the dependency map (CE-WP-0001-T03) layer on top cleanly: `eslint-plugin-boundaries` reads the same `tsconfig` paths. - No application dependencies are installed in this task — only the toolchain. Subsequent workplans install PDF, drag-and-drop, etc. on demand and record them in their own ADRs where the choice is non-obvious.