Reference: Web Model
Vox embraces a server-first web architecture. In Vox v0.3+, the v0.2 @island decorator (colon-syntax) has been modernized to the v0.3 brace-syntax system alongside raw programmatic HTTP routing.
Interactive Islands
Client-side interactive user interfaces are modeled using hydrated React components known as islands.
@island ComponentName { props: ModelType }
Compiles into a TypeScript/React TSX artifact injected via hydration into static HTML generated server-side.
Using Functional State Hooks (react.use_state)
Because Islands are fully bridged React outputs, you can instantiate frontend React state mapping hooks seamlessly.
// vox:skip
import react.use_state
@island
fn ToggleBtn() -> Element {
let (on, set_on) = use_state(false)
<button onClick={fn() set_on(!on)}>
{if on { "Active" } else { "Inactive" }}
</button>
}
Inner JSX Rules
Inside the body of any function that returns Element, you can directly emit standard JSX elements. Note that:
- Variables are evaluated implicitly within
{braces}. - Handlers (
onClick,onChange) capture inline lambda functions implicitly. - You do not need to call
ret <div/>; trailing expressions resolve correctly.
Inline HTTP Layout Mappings
Vox enables inline API mapping without full standalone Axum scaffolding using raw web directives.
http get "/path" -> ResultType { }
Triggers a standard asynchronous GET routing returning raw string, UI templates, or JSON output payloads depending on structural data boundaries.http post "/path" (body: BodyType) -> ResultType { }
Determines direct incoming payload structures explicitly mapped inside Vox structural ADT data types.
routes { } (canonical syntax, 2026)
Vox emits a routes.manifest.ts (VoxRoute[]) for adapters; the normative surface in .vox is:
- Paths: string literals with
tobefore the component name:"/" to Home. - Loaders / pending:
with loader: myQueryand/orwith pending: Spinner(tuple formwith (loader: a, pending: b)supported). - Nesting: child routes inside
{ ... }after the parent entry (path strings only inside nested blocks). - Global screens:
not_found: NotFoundPageanderror: ErrorPagein theroutes { }body.
Deferred (not in the parser yet): "/path" as layout Shell { }, under LayoutName, redirect-only entries, wildcard segments, and populating RouteEntry.redirect / is_wildcard from source — see react-interop-implementation-plan-2026.md and tanstack-start-codegen-spec.md (historical examples may overshoot grammar).
Route table (legacy arrow sketch)
Older prose used arrow forms; prefer to and manifests per vox-web-stack.md.
// vox:skip
routes {
"/" to Home
"/dashboard" to AccountDashboard
}
Compilation and Hydration (Behind the scenes)
When generating code, the @island component operates as follows:
- Vox generates standard server-side HTML representations containing unique ID markers matching
data-vox-island="ComponentName". - A separate module bundle named
island-mount.jsis automatically resolved and built during compilation. - When the user loads the page,
island-mount.jsdetects the presence of the DOM attributes and runs automatic progressive hydration locally over that explicit piece of DOM tree.