A minimal NATS client written in Zig.
Built as a learning project and portfolio piece targeting Zig 0.16.0-dev and the new std.Io async API.
It implements enough of the NATS protocol to connect, publish, and subscribe over a real broker across physical devices.
⚠️ This is not a replacement for a full NATS client — it covers a small subset of the protocol sufficient for a specific use case.
Working but intentionally minimal. This is not a production client.
What works:
- TCP connection and NATS handshake
- Publish and subscribe
- Automatic PING/PONG keepalive
- Multiple subscriptions with per-subject handlers
- Tested against NATS Server 2.11.6
Not implemented (v1):
- TLS
- Authentication
- JetStream / persistent streams
- Cluster awareness or reconnection
- Wildcard subject matching on the client side
- Zig
0.16.0-devnightly — thestd.Ionetworking API is not available in stable releases - A running NATS server — nats.io
const std = @import("std");
const Io = std.Io;
const znats = @import("znats");
fn onMessage(msg: znats.NatsMsg) void {
std.log.info("received on {s}: {s}", .{ msg.subject, msg.payload });
}
pub fn main(init: std.process.Init.Minimal) !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var threaded: Io.Threaded = .init(gpa.allocator(), .{
.argv0 = .init(init.args),
.environ = init.environ,
});
defer threaded.deinit();
const io = threaded.io();
var client = try znats.Client.connect(gpa.allocator(), io, "127.0.0.1", 4222);
defer client.deinit();
_ = try client.subscribe("my.subject", onMessage);
try client.run();
}Start a NATS server:
nats-serverUpdate NATS_HOST in the example files to point at your broker, then in two terminals:
zig build subscribe
zig build publishsrc/
root.zig # public API surface
client.zig # Client type — connect, publish, subscribe, run
connection.zig # TCP layer — read/write primitives over std.Io.net
protocol.zig # NATS protocol parser and serializer
examples/
subscribe.zig # receive and print incoming messages
publish.zig # send a single detection event
The Unlicense