NullHub: a manifest-driven 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 is a single Zig binary with an embedded Svelte UI that installs, supervises and monitors NullClaw and its sibling components. The interesting part is not the dashboard, it is the manifest contract that lets the binary stay generic.
- Who is it for?
- Adopt NullHub if you already run NullClaw, NullBoiler, NullTickets or NullWatch and want one local process to install, supervise and monitor them without a hosted control plane. Do not adopt it as a general-purpose agent orchestrator: it is a generic engine that only knows what a component's nullhub-manifest.json tells it, so a component without a manifest is not manageable through it.
- 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 59 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 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem NullHub actually solves: four binaries and no front door
The Null ecosystem is a set of separate programs. NullClaw is the agent runtime, NullBoiler handles orchestration workflows, NullTickets is a tracker with a key-value store, and NullWatch records run traces. Running them together means four install procedures, four config file formats, four ways to check whether something is alive, and at least one integration (NullTickets to NullBoiler) that has to be wired by hand. NullHub exists to collapse that into one binary. The README describes it as "the simplest way to install, configure, and manage NullClaw" and then widens the scope to the whole ecosystem. The target user is a single operator or a small team running these components on one machine or one small host, not a platform team with a Kubernetes cluster. The CLI surface confirms this: nullhub status prints a table of instances, nullhub logs tails one, nullhub start-all and stop-all operate in bulk. That is a local operator's vocabulary.
The manifest engine is the design decision that matters
NullHub is not hardcoded to know how NullClaw installs. According to the README, each component publishes a nullhub-manifest.json that describes installation, configuration, launch, health checks, wizard steps and UI modules, and NullHub is "a generic engine that interprets manifests." That is the load-bearing choice. It means the install wizard, the config editors and the health checks are all driven by data the component ships, so adding a fifth component should not require patching NullHub itself. It also sets the failure mode: a component with a stale or missing manifest gets a degraded experience, because the engine has nothing to interpret. The README does not document the manifest schema, which is a real gap for anyone who wants to write one or debug a wizard step that behaves oddly. You would be reading the manifest files in ~/.nullhub/ to learn the format.
Architecture: one process, two modes, three proxies
The binary runs in one of two modes. In server mode it runs the HTTP server plus supervisor threads. In CLI mode it makes direct calls, writes to stdout and exits. The frontend is SvelteKit with the static adapter, pulled into the binary with @embedFile, so the built artifact no longer needs a runtime ui/build directory. Component UI modules such as chat and monitor are loaded dynamically through Svelte 5 mount(). All state lives under ~/.nullhub/ (config, instances, binaries, logs, cached manifests). The proxy layer is where the cross-component story lives. Requests to /api/nullboiler/* reverse-proxy to NullBoiler's REST API using NULLBOILER_URL and an optional NULLBOILER_TOKEN. Requests to /api/nulltickets/store/* go to NullTickets via NULLTICKETS_URL and NULLTICKETS_TOKEN. Requests to /api/nullwatch/* go to the managed NullWatch instance, with NULLWATCH_URL able to override the target and NULLWATCH_TOKEN able to override the managed token. That proxy design keeps the browser talking to one origin, which is why the CORS flag exists at all.
Getting it running, and the two runtime dependencies people miss
The documented build is two commands: zig build, then ./zig-out/bin/nullhub. The server opens a browser at http://nullhub.localhost:19800, and the README lists the local access chain as nullhub.local:19800, then nullhub.localhost:19800, then 127.0.0.1:19800. NullHub tries to publish nullhub.local through dns-sd or avahi-publish when those tools exist and falls back down that chain when they do not, so on a machine without mDNS you land on the localhost name. Two runtime prerequisites are easy to overlook: curl is required to fetch releases and binaries, and tar is required to extract UI module bundles. npm is required for zig build and for any build that embeds the Svelte UI, though backend-only tests can skip it with zig build test -Dembed-ui=false -Dbuild-ui=false. The README states that when these tools are missing, nullhub attempts to install them through whatever package manager it finds among apt, dnf, yum, pacman, zypper, apk, brew, winget and choco. A management tool that installs its own dependencies is convenient and also a thing to think about before running it on a machine you care about. For automation, nullhub api GET /api/instances/nullclaw/<name>/status --pretty and the equivalent cron route give you scriptable access without the UI. Instance addressing is {component}/{instance-name} everywhere, including nullhub config, nullhub logs and nullhub update.
Where NullHub is the wrong tool
NullHub supervises local processes. The README describes start, stop, restart and crash recovery with backoff, plus periodic HTTP health checks. There is no mention of remote agents, cluster scheduling, or running components on more than the host NullHub itself runs on. If your agents need to run across a fleet, this is the wrong layer, and the proxy routes assume the target services are reachable from the NullHub process. The second boundary is the manifest dependency: NullHub cannot manage a component that does not ship a nullhub-manifest.json, so it is not a general supervisor you can point at arbitrary binaries. Third, the update path is one-click download, config migration and rollback on failure, which is convenient but means you are trusting the component's own migration logic during an upgrade. The README does not describe what rollback does to state written by a newer version, and that is the question I would want answered before letting update-all run unattended against instances holding data. Finally, the README does not document the manifest schema, the storage layout in detail, or what happens when two instances of the same component claim the same port. Those are documentation gaps, not necessarily design flaws, but they are gaps you will hit.
How it differs from a configuration-management tool
The obvious alternative for someone running several services on one box is a general configuration-management or service-management tool: systemd units written by hand, or Ansible playbooks that install and template configs. The difference in approach is where the knowledge lives. With systemd or Ansible, you encode each component's install steps, config paths and health check in your own repository, and you maintain that encoding as the components change. NullHub pushes that knowledge upstream into the component's nullhub-manifest.json and keeps the engine generic, so the install wizard and config editors follow the component rather than your playbook. The trade is control. A hand-written systemd unit does exactly what you wrote and nothing else; NullHub's installer decides what to download and where to put it under ~/.nullhub/. If you need an auditable, reproducible deployment where every artifact is pinned and reviewed, the manifest-driven approach hides those decisions behind a component you did not write. NullHub also gives you something Ansible does not: a live dashboard with log streaming over SSE, health status cards, and a Mission Control page that replays a deterministic local scenario with workflow execution, role-based agents, failure, checkpoint recovery and telemetry. That last piece is a demo surface as much as an operations surface, and the README is explicit that it does not require hosted infrastructure or model secrets.
Maintenance, releases and the MIT licence
The repository is active, not archived, with a last push in July 2026 and three releases in the visible window: v2026.3.21, v2026.4.17 and v2026.5.29. The version scheme is date-based, which makes it easy to see how far behind an instance is but tells you nothing about semantic compatibility between releases. The README does not publish a compatibility matrix between NullHub versions and component manifest versions, so an update to NullHub and an update to a component could in principle move the manifest contract in opposite directions. That is the upgrade cost to plan for: not the download, but the coordination. On licensing, the repository is MIT. That is permissive and short, but it covers NullHub's own source, not the components it installs, which are separate repositories with their own licences. If you redistribute a binary built with an embedded Svelte UI, the bundled frontend dependencies carry their own licence obligations, and the README does not enumerate them. That is a question for whoever reviews your distribution, not something this article can settle.
Editorial conclusion
Adopt NullHub if you already run NullClaw, NullBoiler, NullTickets or NullWatch and want one local process to install, supervise and monitor them without a hosted control plane. Do not adopt it as a general-purpose agent orchestrator: it is a generic engine that only knows what a component's nullhub-manifest.json tells it, so a component without a manifest is not manageable through it. Before committing, verify three things on your own machine: that your target component actually publishes a nullhub-manifest.json, that curl and tar are present or that the automatic package-manager install path works on your distribution, and that the port 19800 and the nullhub.local dns-sd or avahi-publish name resolution behave as you expect on your network.
Community notes