NullHub: a Zig management console for the NullClaw agent stack
Management console for the Null ecosystem — install, configure, and monitor AI agents, orchestration workflows, task pipelines, and system health
At a glance
- What is it?
- NullHub installs, supervises and monitors the Null ecosystem from one binary with a Svelte UI embedded in it. It is manifest-driven, local-first, and only as useful as the components you run under it.
- Who is it for?
- Adopt NullHub if you already intend to run NullClaw or its sibling components on a machine you control and want one place to install, supervise and inspect them. Do not adopt it if you only want a hosted agent service, or if you are unwilling to install npm and curl, since zig build embeds the Svelte UI and the runtime fetches releases with curl.
- 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 74 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 September 26, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What NullHub actually manages, and for whom
NullHub is a management console for the Null ecosystem. The README names four components it installs, configures, monitors and updates: NullClaw, NullBoiler, NullTickets and NullWatch. It describes itself as "the simplest way to install, configure, and manage NullClaw", so the primary target is someone who has decided to run NullClaw and now needs somewhere to put the configuration, the process lifecycle and the logs.
The audience is narrower than a general agent framework. NullHub is not an agent runtime. It does not execute workflows itself, and the Mission Control page runs a "deterministic local replay scenario" rather than a live hosted service. It is a control plane: a Zig HTTP server, a process supervisor, an installer and a manifest engine, with a Svelte frontend compiled into the same binary. If you never install a component, NullHub has almost nothing to show you.
The practical case is a single machine, probably a workstation or a small server, where several Null components need to run side by side and talk to each other. The README's local access chain (nullhub.local, nullhub.localhost, 127.0.0.1 on port 19800) makes that assumption explicit. There is no documented multi-host mode.
Manifests, proxies and the ~/.nullhub state directory
The architecture is manifest-driven. Each component publishes a nullhub-manifest.json that describes installation, configuration, launch, health checks, wizard steps and UI modules. NullHub calls itself "a generic engine that interprets manifests", which is the design decision that matters most here: adding a component means publishing a manifest, not patching NullHub.
State lives under ~/.nullhub/, covering config, instances, binaries, logs and cached manifests. Instance addressing uses {component}/{instance-name} everywhere, so the same identifier works in the CLI, in the API and in the UI. That consistency is worth noting because it is what lets the CLI be scripted against the same objects the browser shows.
Three reverse proxies sit in front of the sibling components. Requests to /api/nullboiler/* go to NullBoiler's REST API via NULLBOILER_URL (for example http://localhost:8080) with an optional NULLBOILER_TOKEN. Requests to /api/nulltickets/store/* go to NullTickets via NULLTICKETS_URL and an optional NULLTICKETS_TOKEN. Requests to /api/nullwatch/* go to the managed NullWatch instance, with NULLWATCH_URL able to override the target for an external instance and NULLWATCH_TOKEN overriding the managed token. The NullWatch page is documented as displaying run summaries, spans, evals, latency, cost and failure context "without sending data to hosted services", which is the local-first claim in concrete form.
The frontend is SvelteKit with a static adapter, embedded into the binary via @embedFile, with component UI modules such as chat and monitor loaded dynamically through Svelte 5 mount(). The README states that the resulting binary includes the built web UI and "no longer depends on a runtime ui/build directory", so the build and the runtime have different requirements.
Building NullHub and running a first component install
NullHub builds from source. The README's quick start is two commands, and the build embeds the Svelte UI, so npm is required for zig build. Backend-only tests can skip the UI with the flags shown in the README.
zig build
./zig-out/bin/nullhubThe binary starts the server and opens a browser to http://nullhub.localhost:19800. The README notes that nullhub tries to publish nullhub.local through dns-sd/Bonjour or avahi-publish when available, and otherwise falls back to nullhub.localhost and finally 127.0.0.1. If the browser does not open on the hostname you expect, that fallback order is the first thing to check.
For a headless or remote run, the serve subcommand takes a host, a port and repeatable origin flags. Extra CORS origins can also arrive as a comma-separated list in NULLHUB_ALLOWED_ORIGINS, which is how the README suggests authorizing something like a Tailscale domain.
nullhub serve --host H --port N --allowed-origin ORIGIN
nullhub serveThe NullWatch tutorial in the README is the clearest first real use. Start the server without opening a browser, then use the web UI to install a component.
zig build run -- serve --no-openIn the UI, open Install Component, select NullWatch, keep or set the API port to 7710, and finish the wizard. According to the README, the installer starts the NullWatch instance and the NullWatch proxy discovers it automatically. You should then see the instance in the status table, and nullhub status should list it under the {component}/{instance-name} form.
nullhub status
nullhub status <c>/<n>
nullhub logs <c>/<n> -fThe same wizard is available in the terminal via nullhub install <component>, which is the option to use when there is no browser in the loop.
Where the supervision model and the docs stop short
Process supervision covers start, stop, restart, crash recovery with backoff, and periodic HTTP health checks. That is a reasonable set for long-running local processes, but it is not a general-purpose init system, and the README does not describe resource limits, cgroup integration or dependency ordering between components. If NullBoiler must be up before NullTickets, the documented cross-component linking ("auto-connect NullTickets -> NullBoiler") suggests the installer wires that relationship, but the README does not spell out what happens to that link when one side is stopped and restarted manually.
Updates are the other area where the documentation is thin. NullHub advertises one-click updates that download, migrate config and roll back on failure. The README does not document what a rollback restores, whether it covers the migrated config, or how to trigger a rollback by hand from the CLI. The CLI list shows check-updates, update <c>/<n> and update-all, and nothing named rollback. Treat the rollback claim as a behaviour to verify on a throwaway instance before you rely on it for anything you care about.
There is also a bootstrap dependency worth flagging. Runtime prerequisites are curl, to fetch releases and binaries, and tar, to extract UI module bundles. When those tools are missing, the README says nullhub will try to install them through available system package managers (apt, dnf, yum, pacman, zypper, apk, brew, winget, choco). A management tool that installs its own dependencies through a detected package manager is convenient on a workstation and questionable on a locked-down host. On such a host, install curl and tar yourself and skip that path.
Finally, NullHub is the wrong tool if you want a single self-contained agent. It is a hub. Its value comes from the components underneath it, and every proxy route it exposes (NULLBOILER_URL, NULLTICKETS_URL, NULLWATCH_URL) points at something you still have to run.
NullHub against running the components by hand
The obvious alternative is not another console. It is running each Null component directly and managing it with whatever you already use: systemd units, a process manager, or a shell script plus curl against each component's own API. That approach gives you exactly the lifecycle semantics you wrote, and nothing you did not.
The difference in approach is the manifest. NullHub does not hardcode knowledge of NullClaw or NullWatch; it reads nullhub-manifest.json from each component and interprets installation, configuration, launch, health checks, wizard steps and UI modules from that file. Running components by hand means re-deriving each of those per component, and re-deriving them again when a component changes its launch arguments. The trade is that you inherit a generic engine's assumptions about how components behave, and you get whatever the manifest author chose to describe.
NullHub does offer one escape hatch in the other direction: nullhub service install registers and starts an OS service through systemd or launchd, with service uninstall and service status alongside it. So the hand-rolled systemd route and the NullHub route are not mutually exclusive at the outer layer. What you cannot do is keep NullHub's UI and proxies while discarding its supervisor, because the status cards, logs and health checks all read from the supervised instances.
For teams already standardized on a container orchestrator, the Dockerfile in the repository builds a static musl binary with the UI compiled in, which suggests container deployment is anticipated. The README does not document a compose file or a Kubernetes manifest, so that path is yours to assemble.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-07-19. Releases are dated rather than semantic: v2026.5.29, v2026.4.17 and v2026.3.21. That cadence, roughly monthly across the three most recent tags, is the only maintenance signal available here; the README does not publish a support policy or a compatibility matrix between NullHub and component versions.
Upgrade cost is concentrated in two places. First, the build: zig build embeds the Svelte UI, so an upgrade pulls npm and the UI toolchain back in unless you build with -Dembed-ui=false -Dbuild-ui=false, which the README documents only for backend-only tests. The Dockerfile pins ZIG_VERSION=0.16.0 and builds with -Dtarget=x86_64-linux-musl or aarch64-linux-musl and -Doptimize=ReleaseSmall, so a reproducible build is possible without installing Zig locally.
Second, the config migration on update. The README states that updates migrate config, but it does not describe the migration format or how to inspect a migration before applying it. Since all state lives under ~/.nullhub/, backing up that directory before nullhub update-all is the concrete precaution the layout supports.
Licensing is MIT, which is permissive and places few obligations beyond retaining the copyright and permission notice. That applies to NullHub itself. The components it installs are separate projects with their own licences, and the README does not state what those are. Check each component's repository before redistributing a bundle that includes them. Nothing here is legal advice.
Editorial conclusion
Adopt NullHub if you already intend to run NullClaw or its sibling components on a machine you control and want one place to install, supervise and inspect them. Do not adopt it if you only want a hosted agent service, or if you are unwilling to install npm and curl, since zig build embeds the Svelte UI and the runtime fetches releases with curl. Before committing, run `nullhub status` after one install, confirm the instance directory under `~/.nullhub/` holds the config and logs you expect, and check that the manifest your component publishes is the one NullHub actually reads.
Frequently asked questions
What is NullHub used for?
NullHub is a management console for the Null ecosystem. The README describes it as a single Zig binary with an embedded Svelte web UI for installing, configuring, monitoring and updating NullClaw, NullBoiler, NullTickets and NullWatch.
How do I install NullHub and start it?
The README's quick start is `zig build` followed by `./zig-out/bin/nullhub`, which opens a browser to http://nullhub.localhost:19800. For a headless run, use `nullhub serve --no-open`. Building requires npm because the Svelte UI is embedded into the binary.
Does NullHub need curl and tar installed?
Yes. The README lists curl as required to fetch releases and binaries, and tar as required to extract UI module bundles. When they are missing, NullHub tries to install them through available system package managers such as apt, dnf, brew or winget.
Where does NullHub keep its configuration and logs?
All state lives under `~/.nullhub/`, which the README says holds config, instances, binaries, logs and cached manifests. That directory is also what you would back up before running `nullhub update-all`.
Official sources
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.
[](https://hysenlabs.com/projects/nullclaw-nullhub)