Skip to content

Repository files navigation


DocumentationDeepWikiCoverageBuild Status
zerofmk.inAsk DeepWikiCoverageBuild Status


Zero is a strongly opinionated web framework written in Zig, built on top of http.zig that aims for zero allocations and created to make development easier while keeping performance and observability in mind.

Zero framework is completely configurable, you may isolate and attach best-in-class built-in solutions as you see fit using the 12 Factor App methodology.

Zero framework has useful features like drop-in support for numerous databases, queuing systems, and external services, as well as REST, authentication, logging, metrics, observability, and scheduling.

Zero mascot

zero mascot

Table of Contents

Features

CategoryStatusDetails
REST / CRUDBuild standard REST endpoints out-of-box
Configuration.env with per-environment overrides
LoggingStructured, UTC timestamps
MetricsApp, HTTP, SQL, KV + process/memory stats
TracingTraceID middleware, request-level tracing
Auth MiddlewareBasic, API Key, OAuth 2.0
CORSConfigurable CORS middleware
Panic RecoveryAutomatic panic recovery
DatabasesPostgreSQL, SQLite, Redis
Pub/SubMQTT, Kafka (via librdkafka)
MigrationsDB migrations + seed on startup
HTTP ClientRegister multiple external services
Cron Jobs* * * * * + second-level + range support
WebSocketsBuilt-in WebSocket support
Static FilesServe static assets + Swagger UI
Health ChecksLiveness + status endpoints

See feature_parity.md for the full roadmap and upcoming features.

Requirements

  • Zig 0.15.1 (tested and production baseline)
  • librdkafka — required for Kafka support:
    sudo apt install librdkafka-dev # Linux
    brew install librdkafka # macOS

Installation

Add zero to your project:

zig fetch --save https://github.com/im-ng/zero/archive/refs/heads/main.zip

Quick Start

1. Initialize your project

mkdir zero-web-app &&cd zero-web-app
zig init
zig fetch --save https://github.com/im-ng/zero/archive/refs/heads/main.zip

2. Configure build.zig

constzero=b.dependency("zero", .{});
constexe=b.addExecutable(.{
.name="myapp",
.root_module=b.createModule(.{
.root_source_file=b.path("src/main.zig"),
.target=target,
.optimize=optimize,
}),
});
exe.root_module.addImport("zero", zero.module("zero"));
b.installArtifact(exe);

3. Create config directory

mkdir configs
touch configs/.env

4. Write your app

conststd=@import("std");
constzero=@import("zero");
constApp=zero.App;
constContext=zero.Context;
pubconststd_options: std.Options= .{
.logFn=zero.logger.custom,
};
pubfnmain() !void {
vargpa=std.heap.GeneralPurposeAllocator(.{}){};
constallocator=gpa.allocator();
constapp=tryApp.new(allocator);
tryapp.get("/json", jsonResponse);
tryapp.run();
}
pubfnjsonResponse(ctx: *Context) !void {
tryctx.json(.{ .msg="hello from zero!" });
}

5. Run

zig build run
 INFO [03:23:39] Loaded config from file: ./configs/.env
INFO [03:23:39] Starting server on port: 8080

See full documentation for detailed guides on authentication, databases, cron jobs, websockets, and more.

Project Structure

DirectoryPurpose
src/datasource/PostgreSQL (SQL), Redis (Cache)
src/pubsub/MQTT and Kafka publishers/subscribers
src/cronz/Cron scheduler and job execution
src/migration/Database migrations and seeding
src/mw/Middleware: auth, tracing, websocket
src/service/HTTP client for external services
src/http/Error types and HTTP utilities
src/zsutil/System utils: memory, CPU, process, host
src/static/Embedded Swagger UI assets

Key entry points:

  • src/zero.zig — re-exports all public types
  • src/app.zig — main App struct (App.new(), app.run())
  • src/context.zig — request context with .SQL, .Cache, .GetService()

Configuration

Zero loads config from configs/.env at startup, with per-environment overrides (e.g. configs/.dev.env when APP_ENV=dev).

# Application
APP_NAME=myapp
APP_VERSION=1.0.0
APP_ENV=dev
# Logging
LOG_LEVEL=debug
# PostgreSQL# DB_HOST=localhost# DB_USER=user1# DB_PASSWORD=password1# DB_NAME=mydb# DB_PORT=5432# DB_DIALECT=postgres# Redis# REDIS_HOST=127.0.0.1# REDIS_PORT=6379# REDIS_USER=redis# REDIS_PASSWORD=password# REDIS_DB=0# REDIS_TLS_ENABLED=false# Kafka# KAFKA_BROKER=localhost:9092# MQTT# MQTT_HOST=localhost# MQTT_PORT=1883# Authentication# AUTH_MODE=Basic

All keys are commented out by default; features activate only when uncommented. See config.md for the full list.

Examples

14 example applications are available in the examples/ directory:

ExampleDescription
zero-basicMinimal HTTP server
zero-authAuthentication (Basic, API Key, OAuth)
zero-cronzCron job scheduling
zero-kafka-publisherKafka message publishing
zero-kafka-subscriberKafka message consumption
zero-mqtt-publisherMQTT message publishing
zero-mqtt-subscriberMQTT message consumption
zero-redisRedis cache operations
zero-sqliteSQLite database usage
zero-migrationDatabase migrations
zero-service-clientExternal HTTP service client
zero-streamStreaming responses
zero-todo-htmxHTMX-powered CRUD app
zero-websocketWebSocket connections

Each example has its own build.zig and build.zig.zon.

Testing

zig build test# run all unit tests (52 tests)
zig build --release=fast # release build
make clean # remove build artifacts

Benchmark

ConfigurationRequests/sec
Metrics + logging + tracing + info logging~16,500
Metrics + logging + tracing~29,800
Metrics + logging (no tracing)~31,000
No metrics~31,200

Baseline (none log level): ~83,000 req/s over 100s with 100 concurrent connections.

❯ go-wrk -c 100 -d 100 http://localhost:8080/json
Running 100s test @ http://localhost:8080/json
100 goroutine(s) running concurrently
8344879 requests in 1m39.643117619s, 1.39GB read
Requests/sec: 83747.67
Transfer/sec: 14.30MB
Overall Requests/sec:	83430.16
Overall Transfer/sec:	14.24MB
Fastest Request:	84µs
Avg Req Time: 1.193ms
Slowest Request:	19.669ms
Number of Errors:	0
10%: 124µs
50%: 150µs
75%: 164µs
99%: 175µs
99.9%: 176µs
99.9999%: 176µs
99.99999%: 176µs
stddev: 743µs

Zig Version Compatibility

VersionCompilesTestsRuntimeNotes
0.15.152/52Production baseline
0.15.252/52Production
0.16.0N/AN/ABuild system API changed

Known Gotchas

  • rdkafka is linked as a weak system library — builds fail without librdkafka-dev
  • Always rm -rf .zig-cache zig-out zig-pkg/ before switching Zig versions
  • src/cronz/scheduler.zig and src/mw/authProvider.zig use @import("../zero.zig") (relative path), not @import("zero")

Attributions

See attribution.md for details.

License

Apache License

About

Simple and opinionated web framework written in zig

Topics

Resources

Stars

21 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages