verve · open source
Full-stack web in pure Zig.
SSR with fine-grained reactivity, per-island WASM code splitting, single-binary deploy. No VDOM. No macros. No third-party dependencies. Targets Zig 0.16.
the bet
SSR-first.
Pages render server-side as Node trees streamed straight to the socket. Search engines and noscript clients see real content. No hydration handshake required to read the page.
Real reactivity.
The same Signal / Effect / Owner / Resource graph the server uses ships into a wasm32-freestanding client runtime. DOM updates are a consequence of Signal.set — not a parallel write path tacked on for interactivity.
One binary.
No Node runtime. No build server. No bundler config. zig build produces a single executable with the WASM client, per-island chunks, JS bridge, public assets, and manifest baked in. Deploy by scp.
what's in the box
Routing + rendering
- Comptime route parser with path params, wildcards, nested layouts.
- ProtectedRoute guards + Redirect sentinel.
- useLocation, RequestMeta (cookies, Accept-Language, etc).
Reactivity (server + WASM)
- Signal / Effect / Store / Resource — SolidJS-style runtime.
- Owner tree with on_cleanup, untrack, batch.
- Keyed-list reconciler with LIS-based diff planner.
Head + components
- setTitle / metaTag / linkTag / jsonLd with priority + replace-not-append.
- provide / use DI through the owner chain.
- show / forEach / portal — control-flow helpers.
Auth + security
- CSRF HMAC-SHA256, auto-issued cookie + __csrf field.
- Per-request CSP nonce stamped onto every <script> / <style>.
- Origin pinning, SameSite=Strict on the CSRF cookie.
SSR + client
- Streaming SSR over std.http.Server, chunked transfer-encoding.
- Typed server-fn client stubs generated at build time.
- Out-of-order Suspense streaming with <template> drains.
Islands
- Per-island WASM chunks, ~73 B each via shared linear memory.
- Build-time manifest codegen walks app.islands at comptime.
- Lazy JS bridge fetches each chunk on first encounter.
Assets + i18n
- Static asset routing at /public/* — runtime or comptime-embedded.
- Hashed URLs with immutable Cache-Control headers.
- I18nCatalog + resolveLocale (cookie → query → Accept-Language).
Dev + ops
- --dev auto-reload via WS-disconnect-reconnect.
- /events SSE + /ws bidirectional WebSocket.
- /health + /metrics, per-connection worker pool, systemd socket activation.
install
Three commands, one binary.
Prebuilt binaries ship for linux and macos on x86_64 and aarch64. From source it is exactly one tool — zig — and one build file.
zig version # expect 0.16.0
zig build # native server + WASM client + per-island chunks
./zig-out/bin/verve-server # http://127.0.0.1:8080Docs: github.com/sirhco/verve/tree/main/docs. Showcase example exercises every public export.
live demos
This page runs on Verve.
The counter below is an island. The framework ships a small WASM chunk fetched on demand, shares linear memory with the main client, and hydrates the bound span. Clicks below are real Actions: each form POSTs to /api/<name>, the framework verifies the CSRF token from the cookie + hidden field, calls the typed Zig function, and the redirect-back reflects the new value.
01 · island + actions
counter island · WS push · zero reload
open source · pre-1.0
github.com/sirhco/verve
background reading
Why I write Zig covers the language case. the Verve case study covers the framework decisions.