Library / SDK
karlseguin/http.zig avatar
karlseguin/http.zig

karlseguin/http.zig: HTTP/1.1 routes, state and dispatch

An HTTP/1.1 server for zig

1,621 stars132 forksZigMIT

At a glance

What is it?
http.zig gives Zig developers direct control over HTTP/1.1 routing, shared state, custom dispatch and shutdown without wrapping std.http.Server. Its dependency model follows Zig compatibility branches and the repository has no published GitHub releases.
Who is it for?
http.zig fits Zig developers who want direct control over routing, handler state, dispatch, middleware and shutdown without adopting a larger framework. It is less suitable for teams that require a published release train, broad framework features or compatibility beyond the branch-specific Zig version.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Zig, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

http.zig's place below higher-level Zig web frameworks

http.zig provides an HTTP/1.1 server implemented in Zig without wrapping std.http.Server. Its direct audience is developers building network services in Zig who need request routing but do not want a higher-level framework to dictate the application structure. The README identifies JetZig and Tokamak as higher-level alternatives and says both are built on top of httpz. That places http.zig closer to the server foundation on which those frameworks build.

The project covers more than accepting TCP connections. Its README includes sections on httpz.Request, httpz.Response, path parameters, middleware, custom dispatch, per-request context, metrics, testing, HTTP compliance, Server Side Events and WebSocket support. The repository also includes examples for advanced routing, file uploads, shutdown and HTML streaming. This is enough breadth for services with conventional HTTP routes, but it should not be confused with a complete application framework. The README does not identify an authentication system, session store, template engine or form parser.

The server takes a different implementation position from Zig's standard HTTP server. The README says http.zig does not use std.http.Server and describes the standard server as slow and based on assumptions about well-behaved clients. It reports that a basic request can reach 140K requests per second on an M2, but it does not publish enough benchmark configuration to reproduce or assess that claim. The traceable point is architectural: http.zig owns its server implementation rather than inheriting std.http.Server's behavior.

That distinction is attractive when an engineer needs control over dispatch, middleware and client handling. It also makes protocol review more important. The HTTP Compliance section is named in the table of contents, but the README does not enumerate its supported methods, malformed-request behavior or response edge cases. The project should be evaluated as an HTTP/1.1 library, not treated as HTTP/2 or HTTP/3 support based on name alone.

Server, Router and handler flow in http.zig

The documented request path starts with a typed server. The introductory program calls httpz.Server(void).init with an I/O instance, allocator, address configuration and handler value. It then creates a router with server.router(.{}), registers a route with router.get and starts serving through server.listen(). The final call blocks until serving ends.

The generic handler type determines what application state route actions receive. The README uses void for a simple service, in which case the server receives a void value. For an application that owns a database pool, the same API can use a pointer type such as *App. The pointer passed to Server(*App).init becomes available to every action. This provides a direct route-level interface without requiring handlers to reach through global state.

Routes support named path segments. The README registers `/api/user/:id`, then calls req.param("id") in the action. Responses are built through httpz.Response. A handler can set `res.status` and call `res.json` with a Zig value. These APIs keep path extraction, application logic and response encoding in a normal Zig function.

Custom dispatch adds a layer between the server and the selected route action. A public `dispatch` method can receive an httpz.Action, request and response. It can invoke the action, decline to invoke it or perform work around the invocation. The README demonstrates timing around the action call, but also describes authentication-oriented dispatch. Shared application data should remain shared, while data derived from one request, such as an authenticated user, belongs in a new RequestContext created for that dispatch. This avoids placing mutable request state on the concurrently used *App instance.

Installing http.zig and registering a first API route

The README states that this version targets Zig 0.17.0. It says master follows the latest stable Zig release, dev follows the latest development version, and branches named `zig-X.YY` are available for older versions. The selected branch therefore matters before installation.

Save the dependency in build.zig.zon with the documented command:

bash
zig fetch --save "git+https://github.com/karlseguin/http.zig#master"

The next step is in build.zig. Resolve `httpz` as a dependency using the executable's target and optimization mode, then add its module to the executable root module:

zig
const httpz = b.dependency("httpz", .{
    .target = target,
    .optimize = optimize,
});

// the executable from your call to b.addExecutable(...)
exe.root_module.addImport("httpz", httpz.module("httpz"));

The README example binds the server to localhost port 5882, registers `/api/user/:id` and returns JSON when `listen()` is running. The repository's example_1 target provides a separate build to inspect:

bash
zig build example_1

The README shows that example listening at `http://localhost:8800/`. Do not confuse that port with port 5882 from the introductory application. A first adoption check should run the repository examples under the exact Zig version used by the service, because a matching compiler and dependency branch are prerequisites to diagnosing application code.

Allocation, shutdown and middleware responsibilities

http.zig uses an allocator supplied to Server.init, and its basic example releases server resources explicitly. The deferred sequence calls server.stop() before server.deinit(). According to the README, stop provides a clean shutdown and finishes serving live requests. That order gives active requests a chance to finish before server resources are destroyed.

The README has a dedicated Memory And Arenas section, indicating that allocation behavior is part of the library's intended design. It does not state default request-body limits, connection limits or arena retention policies. For a service accepting uploads, those omissions deserve attention. The repository includes `examples/10_file_upload.zig`, but the existence of that example does not establish a production body-size or disk-use policy.

Middleware is an extension point rather than a complete policy layer. The repository includes `examples/06_middleware.zig` and a `middleware` directory. Applications can use that path for cross-cutting behavior, while dispatch can focus on preparing per-request context or timing each action. The README does not document a built-in role-based authorization model, token validation or CSRF policy. Those requirements need application code or separate components.

For repository development, the Makefile defines test commands that differ by blocking mode. `make t` runs the complete target with reference tracing in both modes, while `make tn` and `make tb` select the non-blocking and blocking variants. These are specific checks for contributors changing http.zig itself. They do not replace application-level load tests, and the README does not document a benchmark harness for adopters.

Branches, releases, license and upgrade constraints

The repository is not archived, and the last push was on 2026-10-14. It has no GitHub releases. Consequently, there is no published GitHub release number that can serve as a conventional dependency or production baseline. The README's version strategy is branch based: master follows stable Zig, dev follows development Zig, and `zig-X.YY` branches pin older versions.

That model has a direct consequence for upgrades. A dependency fetched from master follows that branch rather than a tagged release artifact. A project that requires reproducible upgrade decisions must identify and record the intended branch, and it must check that branch's stated Zig compatibility. The README does not provide a release cadence or compatibility matrix beyond those branch descriptions.

The repository is identified as MIT licensed. Adopters still need to read the repository's LICENSE file and review licenses for their other dependencies. This article does not interpret the license terms.

JetZig and Tokamak are the relevant documented alternatives when a larger framework is acceptable. Their documented approach is to build on httpz and include more application-level functionality. http.zig instead exposes the server, Router, Request, Response, middleware and dispatch boundary directly. Choose http.zig when those extension points matter and the team is prepared to own more application structure. Verify the `httpz` import, the selected Zig branch, the Request and Response APIs your handlers need, and the behavior of `server.stop()` for streaming and long-lived requests first. The shutdown behavior is the final project-specific boundary to settle before putting the service on its intended traffic path.

Editorial conclusion

http.zig fits Zig developers who want direct control over routing, handler state, dispatch, middleware and shutdown without adopting a larger framework. It is less suitable for teams that require a published release train, broad framework features or compatibility beyond the branch-specific Zig version. Before adoption, verify the Zig version against the selected branch, inspect the Request and Response APIs required by the application, and review the documented behavior of `server.stop()` for long-lived requests.

Frequently asked questions

Which Zig version does http.zig target?

The README says this version is for Zig 0.17.0. It also says master targets the latest stable Zig release, dev targets the latest development version, and `zig-X.YY` branches cover older versions.

How do I add http.zig to a Zig project?

Run `zig fetch --save "git+https://github.com/karlseguin/http.zig#master"`, then resolve the `httpz` dependency in build.zig and add its module to the executable root module.

How can an http.zig handler share application state?

Use a non-void handler type and pass the shared instance to `Server(H).init`. Request-specific state should be placed in a per-request `RequestContext`, because the README says the shared handler is used concurrently.

Does http.zig include WebSocket examples?

Yes. The README table of contents contains a WebSocket section, and the repository includes `examples/08_websocket.zig`. The README does not document the complete WebSocket API.

What alternatives to http.zig does the README list?

The README lists JetZig and Tokamak as higher-level alternatives and says both are built on top of httpz. Their approach adds more framework functionality, while http.zig exposes lower-level server and dispatch controls.

Official sources

  1. Issues
  2. karlseguin/http.zig on GitHub
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/karlseguin-http-zig.svg)](https://hysenlabs.com/projects/karlseguin-http-zig)

Was this useful?