Skip to content

kzig

KickJS for Zig: modules, controllers, services, middleware, context contributors and adapters, with KickJS's boot order and request pipeline. It is built on comptime instead of decorators, so a missing service or an unknown handler fails zig build, not the first request.

Pre-alpha

APIs will change. Requires Zig 0.17.0. The roadmap says what's done, what's next, and where kzig differs from KickJS on purpose.

pub const HelloController = struct {
    hello: *HelloService, // a missing service is a compile error

    pub const routes = .{
        .{ .method = .GET, .path = "/", .handler = "index" },
    };

    pub fn index(self: *HelloController, ctx: *kzig.Ctx) !HelloService.Greeting {
        return self.hello.greet(ctx.arena, "World"); // sent as 200 JSON
    }
};

pub const HelloModule = kzig.Module(.{
    .name = "HelloModule",
    .path = "/hello",
    .controllers = &.{HelloController},
    .services = &.{HelloService},
});

New here? The tutorial builds a complete API, from kzig new to a Docker image: SQLite with migrations, validation, an API key, Swagger UI and tests.

What's in it

Modules and DI Services wired by type at compile time; a cycle or a missing service fails the build
Middleware and contributors Typed context values (got.tenant), ordered by what they read
Validation and settings Bodies, queries and params decoded into types; settings sections from the environment
Adapters KickJS's lifecycle hooks, health checks, graceful shutdown
Uploads and storage Multipart with limits; disk and S3 (SigV4, no SDK)
Database Postgres without libpq (TLS, client certs), kick/db's schema, builder, relations and migrations
SQLite, Turso, D1 The same layer on local files, Turso over HTTP and Cloudflare D1
WebSockets and jobs Gateways with rooms and heartbeats; cron with timezones
OpenAPI The spec from the types, Swagger UI and ReDoc
CLI and testing kzig new, dev, generators; the whole pipeline in-process
API reference Every public declaration, from the source's doc comments