Compile-time routing
A route table is a comptime tuple. Auth, permission codes, OpenAPI parameters and the handler sit together, and duplicate paths fail before startup.
Zig 0.17 · v0.42 · MIT
zmodu is a framework for Zig: routes and dependencies resolve at compile time, while workers and mailboxes stay bounded at run time. The same codebase grows from a modular monolith into a replayable, observable execution platform.
brew install chy3xyz/tap/zmodu
Capabilities
A route table is a comptime tuple. Auth, permission codes, OpenAPI parameters and the handler sit together, and duplicate paths fail before startup.
Declared dependencies are checked at startup: missing, self and cyclic edges stop the application. Run in one process until the boundary is real.
Worker, mailbox, MPSC and TimerWheel. One thread owns state, and a full queue returns error.Full instead of growing.
A controlled clock, random source and event sequence make the same input produce the same order and the same output.
Structured logs, Prometheus metrics, OTLP tracing and runtime readings ship with the framework.
Agents, RAG, approvals and quotas compose as modules. SQLx, Redis, Kafka and the zent ORM stay at the application layer.
Declaration
The handler reads ctx and its own state. Middleware writes identity and permissions, and the route table makes them auditable.
pub const routes = [_]http.RouteSpec(State){
.{ .method = .GET, .path = "{id}",
.handler = get, .meta = .{ .auth = .jwt,
.permission = "order:read" } },
};
Runtime
No global lock in the actor layer. The ticker owns timers, and cross-thread work goes through command queues.
const h = try rt.spawn(.{ .capacity = 1024 });
try h.post(.{ .kind = .tick, .at = now + 50 });
// full: error.Full, not memory growth
The documentation is organised by task: HTTP, modules, runtime, data and AI each stand alone.
Compile-time modularity, ownership-oriented runtime, replayable execution.