Vox full-stack web UI — single source of truth
Vox full-stack web UI — single source of truth
Section titled “Vox full-stack web UI — single source of truth”[!NOTE] Path C (implemented): reactive UI uses
component Name(...) { state ... view: ... }. The@islanddecorator was retired 2026-05-03 — see architecture/external-frontend-interop-plan-2026. Suppress legacy-hook warnings in fixtures withVOX_SUPPRESS_LEGACY_HOOK_LINTS=1(env-vars.md).
Language boundary
Section titled “Language boundary”.voxsource uses only Vox syntax (including Vox JSX-like UI). Do not embed TypeScript or JavaScript in.voxfiles.- TypeScript and React appear only in generated artifacts (
dist/,app/src/generated/) and pnpm scaffolds undercrates/vox-clitemplates. External React frontends import these generated components or call the generatedvox-client.tsdirectly — see architecture/external-frontend-interop-plan-2026.
Shipped stack
Section titled “Shipped stack”| Layer | Role |
|---|---|
vox-compiler / codegen_ts | component, routes {, tables, activities → .tsx / .ts |
vox-compiler / codegen_rust | http, server fns, actors → Axum + rust_embed of public/ |
| Vite + React 19 | Main app under dist/app (scaffolded by vox run / vox bundle) |
@tanstack/react-router | Client routing for routes { (see ADR 010) |
| v0.dev | V0_API_KEY; TSX normalized to named export function Name for routes { imports |
Canonical Frontend
Section titled “Canonical Frontend”[!IMPORTANT]
vox-dashboardis the Single Source of Truth for the Vox user-facing frontend experience (see ADR 030 and ADR 031).apps/editor/vox-vscode/is deprecated and retained only for its LSP client. Ship new MCP behavior, capability UX, and visualization incrates/vox-dashboard/— not in the VS Code extension.
The orchestration dashboard (crates/vox-dashboard/) is the primary Vox user surface. It is served by the Axum backend (vox dashboard command) and communicates with the orchestrator over a local MCP WebSocket proxy. All reactive UI state within the dashboard uses the Vox state_machine compiler primitive as the single source of truth (see below).
Frontend lifecycle ownership (canonical vs experimental vs fixture-only) is tracked in frontend-surface-ownership.md and the machine-readable contract contracts/frontend/surface-ownership.v1.yaml.
- Dashboard entry point:
crates/vox-dashboard/app/src/app.vox— lowered toapp/src/generated/byvox build - Backend:
crates/vox-dashboard/src/— Axum routes, MCP proxy, settings API - Unified Grammar: Vocabulary is synchronized via
tree-sitter-vox/GRAMMAR_SSOT.md. - Retired: Legacy
frontend/(Next.js),packages/vox-ui/, and VS Code as primary surface have been removed/deprecated.
state_machine as SSoT for reactive UI state
Section titled “state_machine as SSoT for reactive UI state”Within the dashboard (and any Vox-generated application), reactive state must be expressed using the Vox state_machine compiler primitive. This primitive is defined in crates/vox-compiler/src/hir/nodes/state_machine.rs, type-checked at crates/vox-compiler/src/typeck/state_machine_check.rs, and lowered to TypeScript+React by crates/vox-codegen/src/codegen_ts/state_machine_emit.rs.
Do not hand-write reactive .tsx files in app/src/generated/ — they must be compiler outputs from .vox sources. The CI gate at scripts/check_dashboard_ssot.vox enforces this rule.
Hand-written React source for the dashboard’s escape-hatch components is explicitly allowed under src/components/. Only the app/src/generated/ subtree is compiler-owned.
Not part of Vox
Section titled “Not part of Vox”Vox does not ship HTML-fragment UIs or classless CSS microframeworks as first-class product paths. Use React + Vite + Tailwind/ShadCN + TanStack Router (→ TanStack Start per ADR 010) for all interactive web UI.
Typed web API client and HTTP verbs
Section titled “Typed web API client and HTTP verbs”vox-client.tsis emitted when the module has any@endpointdeclarations.@endpoint(kind: query)usesGETagainst/api/query/<name>with deterministic JSON-in-query encoding (sorted keys; each argument value is JSON-serialized then URL-encoded). This matches the generated Axum handlers.@endpoint(kind: mutation)and@endpoint(kind: server)usePOSTwith a JSON body — same shapes as Axum.
Normative detail: vox-codegen-ts.md (transport section) and vox-fullstack-artifacts.md.
TanStack Start vs manifest-driven SPA
Section titled “TanStack Start vs manifest-driven SPA”- Vite SPA scaffold (default): when
routes.manifest.tsis present, the scaffold writesvox-manifest-router.tsx+vox-manifest-route-adapter.tsxand drives the router fromvoxRoutes(spa.rs,frontend.rs). - TanStack Start (opt-in): the scaffold still seeds file-based
src/routes/*androuteTree.gen.ts. If the compiler emittedroutes.manifest.ts, the scaffold also addsvox-manifest-route-adapter.tsxas a shared helper you can merge into a programmatic router — it does not replace the default file-routerouter.tsxautomatically.
Mobile browser baseline
Section titled “Mobile browser baseline”For mobile support, this web stack is the primary delivery surface for Vox applications.
- Generated app shells must emit a viewport meta tag and mobile-safe root layout defaults.
- Templates should keep touch ergonomics sane by default (tap-target sizing and responsive spacing in base CSS).
- Mobile support here means browser compatibility for generated Vox apps, not running the full Vox CLI/runtime on-device.
- Keep framework/runtime internals behind WebIR/AppContract/RuntimeProjection boundaries when extending mobile behavior.
External references (ecosystem)
Section titled “External references (ecosystem)”Implementation touchpoints
Section titled “Implementation touchpoints”- Templates:
crates/vox-cli/src/templates/(spa.rs,tanstack.rs;package.json, Vite config). - Frontend build:
crates/vox-cli/src/frontend.rs. - v0:
crates/vox-cli/src/v0.rs,crates/vox-cli/src/v0_tsx_normalize.rs. - React hook mapping /
componentemission:crates/vox-codegen/src/codegen_ts/component.rs(importsreact_bridge: Voxuse_*→ React hooks, shared AST walks). Path C reactive:crates/vox-codegen/src/codegen_ts/reactive.rs,crates/vox-codegen/src/codegen_ts/hir_emit/mod.rs. Server-fn API path prefix:web_prefixes::SERVER_FN_API_PREFIX(HIR + TS fetch URLs stay aligned). Route manifest + typed client:codegen_ts/route_manifest.rs,codegen_ts/vox_client.rs; Start file layout glue lives incodegen_ts/scaffold.rsand CLI templates (tanstack.rs). Opt-out for legacy-hook warnings: envVOX_SUPPRESS_LEGACY_HOOK_LINTS(env-vars.md). vox runauto mode:crates/vox-cli/src/commands/run.rs+commands/runtime/run/run.rs— default is an@pagescan in the first 8 KiB; override with[web] run_modeinVox.toml(auto|app|script) or envVOX_WEB_RUN_MODE(same values; parsed invox-config).- TanStack Start scaffold (opt-in):
Vox.toml[web] tanstack_start = trueorVOX_WEB_TANSTACK_START=1—crates/vox-cli/src/templates.rs+frontend.rsemit Start file layout +@tanstack/react-start(see vox-fullstack-artifacts.md). - External frontend interop (2026):
componentdeclarations lower to plain TSX under the generatedapp/directory; an external React/TanStack/mobile app imports them or calls the endpoints declared in.voxvia the generatedvox-client.ts. SSG HTML shells still come fromvox-ssg+routes {. Full plan: architecture/external-frontend-interop-plan-2026.
Web IR gate matrix (OP-S068, OP-S129, OP-S152, OP-S209): parity and validate thresholds are enumerated under acceptance gates G1–G6 with tests in web_ir_lower_emit.rs, reactive_smoke.rs, pipeline.rs, and full_stack_minimal_build.rs.
Data grids (TanStack Table)
Section titled “Data grids (TanStack Table)”For dense, interactive tables (sorting, filtering, column visibility, virtualization), @tanstack/react-table is the usual fit: headless hooks compose with your design system (e.g. ShadCN data-table patterns). Hand-rolled <table> markup or simple mapped lists stay appropriate when you do not need those features—avoid pulling Table only for static layouts.
Roadmap
Section titled “Roadmap”- TanStack web roadmap — phases Router → Start, SSR, workspace merge.
- TanStack web backlog — checkbox task decomposition.
- ADR 010 — TanStack web spine — decisions (topology, examples, v0,
vox-codegen-htmlretirement). - ADR 012 — Internal web IR strategy — ranked trade-offs and migration plan for compiler-owned frontend IR while keeping React ecosystem interop.
- Internal Web IR implementation blueprint — weighted execution plan and staged task quotas for compiler migration.
- WebIR operations catalog (OP-0001..OP-0320) — ordered, file-by-file operation map with complexity/test/token budgets.
- Internal Web IR side-by-side schema — parser-grounded current-vs-target full-stack representation mapping.
- WebIR K-complexity quantification — token+grammar+escape-hatch delta for the canonical worked app.
- WebIR K-metric appendix — reproducible class registries, worked counts, and equation trace.
Examples (canonical .vox shape)
Section titled “Examples (canonical .vox shape)”examples/STYLE.md— target formatting for golden examples (LLM + human).examples/PARSE_STATUS.md— golden vs optional strict parse (VOX_EXAMPLES_STRICT_PARSE).
Related docs
Section titled “Related docs”- vox-codegen-ts.md —
routes.manifest.ts,vox-client.tstransport (GET@endpoint(kind: query)/ POST mutations). - vox-fullstack-artifacts.md — build outputs, Express
server.tsopt-in, containers. cli.md— CLI includingvox populi(featurepopuli).- TanStack SSR with Axum — dev topology during SSR adoption.
- Mens SSOT — worker/runtime mens registry and HTTP control plane; not emitted by
vox-codegen-*(operator env only). AGENTS.md— architecture index.