Zig 0.17 · v0.42 · MIT

Modules at compile time.
Execution under control.

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.

Install brew install chy3xyz/tap/zmodu
0Zig dependencies
2300+Tests and gates
comptimeRoutes and module graph
2 planesApplication + runtime

Capabilities

What the compiler settles, the runtime does not rediscover.

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.

Module boundaries

Declared dependencies are checked at startup: missing, self and cyclic edges stop the application. Run in one process until the boundary is real.

Bounded runtime

Worker, mailbox, MPSC and TimerWheel. One thread owns state, and a full queue returns error.Full instead of growing.

Deterministic replay

A controlled clock, random source and event sequence make the same input produce the same order and the same output.

Built-in observability

Structured logs, Prometheus metrics, OTLP tracing and runtime readings ship with the framework.

AI and data

Agents, RAG, approvals and quotas compose as modules. SQLx, Redis, Kafka and the zent ORM stay at the application layer.

Declaration

One route, one line of metadata.

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

One thread owns state.
One mailbox owns handoff.

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

Start with one route, or one worker.

The documentation is organised by task: HTTP, modules, runtime, data and AI each stand alone.

Read the docs Best practices

Compile-time modularity, ownership-oriented runtime, replayable execution.