Start
Install
On this page 6 sections
NullWatch ships as a single static binary — 313 to 653 KB depending on target, as measured by the project. It needs no database, no daemon manager and no external services; state lives in plain files under ~/.nullwatch.
Prebuilt binaries
Every release attaches binaries for seven targets:
| Platform | Asset |
|---|---|
| Linux x86_64 | nullwatch-linux-x86_64.bin |
| Linux aarch64 | nullwatch-linux-aarch64.bin |
| Linux riscv64 | nullwatch-linux-riscv64.bin |
| macOS aarch64 (Apple Silicon) | nullwatch-macos-aarch64.bin |
| macOS x86_64 | nullwatch-macos-x86_64.bin |
| Windows x86_64 | nullwatch-windows-x86_64.exe / .zip |
| Windows aarch64 | nullwatch-windows-aarch64.exe / .zip |
Download the one for your machine and make it executable:
curl -LO https://github.com/nullclaw/nullwatch/releases/latest/download/nullwatch-macos-aarch64.bin
chmod +x nullwatch-macos-aarch64.bin
./nullwatch-macos-aarch64.bin serveThere is no Homebrew formula for NullWatch yet.
Docker
A container image is published at ghcr.io/nullclaw/nullwatch (tags latest and v2026.5.29). It runs serve on port 7710 out of the box:
docker run --rm -p 7710:7710 ghcr.io/nullclaw/nullwatch:latestState lives at /nullwatch-data inside the container; mount a volume there if the JSONL data should outlive it.
Build from source
You need Zig 0.16.0 — build.zig.zon declares minimum_zig_version = "0.16.0", so older toolchains won't build it.
git clone https://github.com/nullclaw/nullwatch
cd nullwatch
zig buildThe README drives every command through zig build run:
zig build run -- serveAll examples in these docs use that form. If you installed a prebuilt binary, replace zig build run -- with the binary name (./nullwatch-macos-aarch64.bin serve).
Install through NullHub
If you run the stack under NullHub, it can install and supervise NullWatch like any other managed component:
nullhub install nullwatchNullWatch stays headless either way — it exports a manifest with --export-manifest and accepts wizard answers via --from-json, so NullHub owns the setup UI while NullWatch owns the data. NullHub finds the running service through the NULLWATCH_URL environment variable (for example NULLWATCH_URL=http://127.0.0.1:7710).
Verify
Start the server and check its health endpoint:
zig build run -- serve
curl http://127.0.0.1:7710/healthWhere things live
The first run creates a home directory:
| Path | Purpose |
|---|---|
~/.nullwatch/config.json |
Single JSON config file |
~/.nullwatch/data/ |
JSONL storage for spans, evals and runs |
The default config:
{
"host": "127.0.0.1",
"port": 7710,
"data_dir": "data",
"api_token": null
}data_dir resolves relative to the config file, which is how data becomes ~/.nullwatch/data. Set api_token to require a bearer token on API requests — see the API reference. The E2E suite also uses a NULLWATCH_HOME environment variable to point the binary at an alternate home directory.
Next: seed demo data and take a first reading in the quickstart.