"Vox full-stack build artifacts — single source of truth"

Vox full-stack build artifacts — single source of truth

This document names every major output of vox build / vox run / vox bundle and the canonical runtime for the default product path. It complements vox-web-stack.md and ADR 010 — TanStack web spine.

Canonical path (default)

LayerArtifactRole
HTTP APItarget/generated/src/main.rs (+ lib.rs, …)Axum listens on VOX_PORT (default 3000).
Browser client for @server fndist/api.ts (or out_dir/api.ts from -o)fetch POST to /api/<name>; API_BASE is ''; Vite dev proxy forwards /api to Axum.
Typed web client (vox-client.ts)out_dir/vox-client.ts (with @query / @mutation / @server)GET + JSON query args for @query; POST + JSON body for @mutation / @server (matches Axum).
Route manifestout_dir/routes.manifest.tsvoxRoutes tree for SPA/Start adapters (routes { present).
UIout_dir/*.tsx, out_dir/*.tsReact components + router shell; SPA scaffold uses manifest when present.
Static HTML shellstarget/generated/public/ssg-shells/**From vox-ssg: minimal shells for routes { / @page (hydration anchor, not a second UI runtime).
Embedded static (after frontend build)target/generated/public/**Vite dist/ copied here for rust_embed in release flows.

vox run (app mode): builds TS to dist/, runs cargo run in target/generated — the Rust binary is the primary server.

Legacy / opt-in: Express server.ts

vox-codegen-ts can emit server.ts, an Express app that duplicates @server and http route registration.

  • Default: emission is off unless VOX_EMIT_EXPRESS_SERVER=1 is set in the environment when running codegen (e.g. vox build). The supported client for @server fn against Axum is api.ts from Rust codegen (emit_api_client).
  • Use case for VOX_EMIT_EXPRESS_SERVER=1: Node-only demos, tests, or containers that intentionally run npx tsx server.ts instead of the Rust binary.

Container images

vox-container::generate_default_dockerfile is Rust-first: FROM debian:bookworm-slim, COPY vox-app, CMD ["/app/vox-app"] (place the release binary from vox bundle / cargo build --release in target/generated into the build context as vox-app). @environment blocks and hand-authored Dockerfiles remain the place for a Node + npx tsx server.ts lane (requires VOX_EMIT_EXPRESS_SERVER=1 at codegen). See how-to-deploy.md.

Axum JSON error envelope (API handlers)

  • @mutation with a schema (@table present): the generated handler wraps the body in db.transaction(...) when applicable; a failed transaction maps to Json(serde_json::json!({"error": e.to_string()})).
  • @query, @server, and mutations without that transactional wrapper emit a straight-line handler body; they do not automatically wrap every failure in the same {"error": ...} object. Use application logic inside the handler (or Axum layers) if you need a uniform error shape for those paths.

Optional: islands and v0

  • islands/ — separate Vite app; built by vox run / bundle when islands/package.json exists (frontend.rs).
  • @v0 — TSX on disk under out_dir; named export function required for routes { imports (v0_tsx_normalize.rs).