# ADR 0005: React + Vite single-page application - Status: accepted - Date: 2026-07-04 ## Context The frontend hosts a heavily stateful collaborative editor (ADR 0003/0004), a collapsible pond sidebar, admin UIs, and a plugin sandbox host. It must work offline (PWA) and be maintainable by many independent contributors. SEO for wiki content matters only for publicly readable pages; the separate static project site (dorfteich.cloud) covers marketing needs. ## Decision - **React (current stable) + Vite + TypeScript**, shipped as a static single-page application served by the `web` container (nginx serving `dist/`, with SPA fallback to `index.html`). - Routing: React Router. Server state: TanStack Query. Local/UI state: Zustand where component state is not enough. Forms: react-hook-form + Zod schemas from `packages/shared`. - Styling: CSS custom properties + a small utility layer; the visual design is plain and professional per the vision. Pond-level font configuration (ADR 0016) is applied via CSS variables. - PWA: `vite-plugin-pwa` service worker caches the app shell for offline editor startup (works with `y-indexeddb`, ADR 0003). - **Public read-only pages are server-rendered for crawlers only where needed**: the API exposes a plain HTML rendering endpoint per public page (also used for PDF export, ADR 0009). We deliberately avoid SSR frameworks for the app itself. ## Consequences - Simple deployment (static files + API), no Node server for the frontend. - TipTap's React bindings are first-class; the editor integration follows the officially documented path. - The SPA is the only consumer of the REST API, which keeps the API honest as the boundary for self-hosted automation and future integrations. - SEO for public wiki pages relies on the HTML rendering endpoint being served to crawlers via reverse-proxy rules — documented in `deployment.md` and acceptable for a wiki (dorfteich.cloud handles discoverability of the product itself). ## Alternatives considered - **SvelteKit**: excellent framework and used elsewhere in the operator's projects, but the TipTap/Yjs collaborative-editing ecosystem, examples, and collective experience are strongest in React; for a contributor-diverse open-source project the larger ecosystem wins. - **Next.js**: SSR/ISR complexity buys little for an app that is 95% behind a login or served to a small community; PWA/offline is simpler in a pure SPA.