NUI puts a management console in front of a NATS server
Free and Open Source NATS management GUI.
At a glance
- What is it?
- NUI is a free and open source GUI for NATS core, JetStream streams and KV buckets, shipped as a desktop app, a Docker image and a web build. It gives operators a visual workspace for messages and state, at the cost of putting an extra Go service between you and the broker.
- Who is it for?
- NUI fits an engineer who wants to inspect core NATS traffic, browse and purge JetStream messages, and edit KV entries from a browser or a desktop app rather than from the nats CLI. It does not fit a team that needs audited access control, cluster topology views or server metrics, since the feature list leaves server info, advanced stream and KV operations, and streams backup and restore as items still to come.
- Can I use it commercially?
- Yes. Unlicense 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 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A workspace for one broker, not a cluster control plane
NUI answers a narrow question: how do you look inside a running NATS deployment without memorizing every nats CLI subcommand. The feature list covers core publish and subscribe, request and reply with the response shown next to the request, and message rendering in text, json, hex, protobuf and cbor. On the stateful side it covers JetStream streams, individual stream messages with filtering, purge and per-message deletion, KV buckets, KV entries with editing, and the history of each entry so past updates and deletes can be inspected.
That scope matters. There is no user management screen, no account or operator permission editing, and no cluster topology view in the documented feature set. The item labeled server info and metrics sits under the project's own heading for things that are coming soon or later, alongside streams backup and restore and advanced stream and KV store operations. So this is a single-broker observation tool with a comfortable interface, not a multi-tenant administration console.
Two UI ideas are worth calling out because they shape daily use. Multiple parallel connections are allowed at the same time, and the workspace is arranged as a card stack that you manage as needed. For someone juggling a staging broker and a production broker, or a core cluster next to a JetStream instance, that means the connections live side by side in one window instead of in separate terminals. The desktop app and the web interface expose the same functionality, so you can keep the same layout whether you are on a laptop or looking at a hosted instance.
The Go binary and the React frontend ship as one image
The repository is split into the pieces you would expect from a Wails application: a Go backend under cmd, a React frontend under frontend, and a main.go at the root. The go.mod file names the module github.com/nats-nui/nui and declares a Go 1.25.0 toolchain requirement, which is newer than the Go 1.21 listed under the local build prerequisites, so a local build on the older version will not work.
The dependency list shows how much NATS sits under the hood. The project depends on the NATS server itself at v2.12.7, on the Go client library nats.go at v1.50.0, on nkeys for key handling, and on orbit.go's natssysclient for system information. State is kept in Badger v4 rather than a relational database. HTTP is served through Fiber v2 with a websocket contribution, and the desktop shell is Wails v2 at v2.12.0.
The Dockerfile builds both halves and merges them into an Alpine image. The backend is compiled with a version stamp, the frontend is built with Node 18, and the final image adds a non-root user with uid 1001 before copying the two artifacts in.
EXPOSE 31311/tcpThat port is the only network surface declared in the image, and it is the port the compose file and the entrypoint both key on. Because the frontend is served by the Go process rather than by a separate web server, there is a single container to run and a single process to reason about, which is a genuine simplification compared with splitting the API and the static assets.
Building the web app locally takes two commands
The documented local workflow has three prerequisites: Go, Node 18 and Wails.io. The web path is the shortest one to try, and the project calls it the web app mode.
npm install
make dev-webThe Makefile target behind that second command builds the frontend and then starts the server binary with an explicit database path and a directory of default CDDL schemas:
npm --prefix frontend run build && go run cmd/server/main.go --db-path=db --cddl-schemas-path=./tests/cddlschemas/defaultTwo things follow from that target. The web mode stores persistent data in the db directory, which is why the same path is mounted as a volume in the compose file. And the server is pointed at a schema directory at startup, which is the mechanism behind the CBOR decoding described later in this article.
The desktop path is a single command, and it goes through the Wails toolchain rather than a plain Go run:
make devThat target invokes wails dev and passes arguments for the database path and log output, so the desktop build compiles against the host operating system. A third target exists for producing a distributable binary with the webkit2_41 build tag, which is the tag the project uses for its Linux desktop builds.
Pointing NUI at saved CLI contexts instead of retyping credentials
The compose file in the repository shows how a self-hosted deployment wires up a broker and the interface together, and it introduces a flag that matters for anything beyond a local trial. The NUI service is started with a context directory:
command: ["--nats-cli-contexts", "/subpath/clicontexts"]The volume mapping for that directory is the other half of the story. By pointing NUI at a directory of NATS CLI contexts, the tool can read the connection definitions that the nats CLI already uses, including credentials and server addresses, rather than asking an operator to retype them inside the interface. The compose file also mounts a db directory, which preserves the Badger data directory across container restarts.
The same compose file starts two brokers for testing. One is a plain nats:2.11 image with ports 4222 and 8222 published and a config mounted from the tests directory. The second is a secured variant on port 4223 with a certificates directory mounted in, which tells you that TLS and auth paths are exercised in the project's own test setup. The interface container is published on host port 31312 against container port 31311, matching the port the Dockerfile declares.
One caveat belongs here. The compose file pulls the ghcr.io/nats-nui/nui:edge image, an edge tag rather than a pinned release, so a compose deployment will track moving builds. Pinning the image to a specific version is a decision you have to make yourself, since the compose file gives you no version constraint to copy.
Structured messages need a schema file you supply
Message rendering goes beyond plain text, and the project treats the schema as your responsibility rather than shipping a catalog. Two guides sit under internal/schemas: one for decoding protobuf messages with your own schemas, and one for reading and sending CBOR with optional CDDL schemas.
The mechanism is visible in two places. The Makefile passes a cddl-schemas-path argument pointing at a directory of default CDDL schemas, and the compose file mounts that same kind of directory into the container. In other words, schema resolution is a filesystem lookup rooted at a path given at startup, not a registry the tool queries. If your message types are not in that directory, the interface has nothing to decode them against.
This is the point where a NATS operator has to do actual work before the pretty view is useful. The schema files live in the cddlschemas directory at the top of the repository, and the README points to the two usage guides rather than restating their contents. That is the right split, since a protobuf or CDDL guide is long and version specific, but it also means the decoding feature is opt in by design. A team publishing JSON payloads with a stable schema will find the json view enough, while a team running a compact binary protocol needs to author or import schemas first.
The same tension applies to hex output. Hex is always available as a fallback, but reading raw bytes is exactly what a GUI is supposed to avoid, so the schema path is the difference between a useful tool and a viewer.
Purge, delete and edit are one click away, with no undo path documented
The operational features are the reason many people reach for a GUI in the first place, and they are also where the risk concentrates. The feature list promises stream operations like purge and message deletion, and KV entries that can be viewed, filtered and edited, with entry history showing past updates and deletes. Each KV entry keeps a history, so you can see what a key held before it was overwritten.
The deletion side is the part to think about carefully. Purge removes all messages in a stream, and message deletion removes one message from a stream. Both are irreversible operations on data that may be the only copy. The history feature is explicitly described for KV entries, and the streams backup and restore item is listed as still to come, so for stream messages there is no documented undo and no documented backup path.
That asymmetry is a design boundary worth stating plainly. For KV, NUI gives you an audit trail of values. For streams, the trail runs one way. If your stream data is expensive to rebuild, use the interface to browse and filter, and keep writes and deletes in a scripted path where you control the sequence.
The write features carry a different caveat. Editing a KV entry through the interface performs the write under the credentials of the connection you are using, which is why the CLI context integration matters in practice. An operator pointing NUI at a production context inherits that context's permissions, and the interface offers no separate authorization layer of its own.
The Unlicense, the beta tag and what an upgrade costs you
The project is released under the Unlicense, which is a public domain dedication rather than a permissive license with attribution requirements. There is no per-seat cost and no license key. Practically, that removes licensing from the adoption decision, though it does not remove the question of what your organisation expects from an unmaintained-looking dependency, and the Go, React and NATS libraries the binary links in carry their own licenses.
The release history is short and recent. The newest tagged build is v0.10.0-beta.1 from 2026-09-20, preceded by v0.9.3 on 2026-06-03 and v0.9.2 on 2026-02-26. The last push was on 2026-10-19, so the project is moving. A beta tag is still a beta tag, though, and it signals that the interface and the underlying feature set may still shift between tagged versions. The repository also ships a cddlschemas directory, a docs directory, a tests directory and a dedicated desktop directory, which means the schema format and the packaging can change together with the UI.
The upgrade cost is therefore mostly operational. You are upgrading a container image, a desktop app and a schema directory at once. If you point NUI at a CLI context directory, that directory is read at connection time, so it has to travel with the deployment. And since the compose example tracks the edge tag, an unplanned restart can pull in a build you have not read the notes for.
Nothing in the documentation describes a migration path between versions, so treat a version jump as a rebuild of your workspace rather than an in-place upgrade.
Editorial conclusion
NUI fits an engineer who wants to inspect core NATS traffic, browse and purge JetStream messages, and edit KV entries from a browser or a desktop app rather than from the nats CLI. It does not fit a team that needs audited access control, cluster topology views or server metrics, since the feature list leaves server info, advanced stream and KV operations, and streams backup and restore as items still to come. Before adopting it, check that your broker is reachable on the address you enter, that you can supply a Protobuf or CDDL schema file if you need structured message decoding, and that the Unlicense terms match your organisation's policy on bundled third party code.
Frequently asked questions
How do I install NUI for NATS?
The project offers a desktop app download, a Docker deployment and a Helm chart that is marked experimental. For local development it lists Go 1.21, Node 18 and Wails.io as prerequisites, then npm install followed by make dev-web for the web app or make dev for the desktop app.
What port does NUI listen on?
The Dockerfile declares 31311/tcp as the exposed port, and the compose file publishes it to host port 31312. The compose file also starts NATS on 4222 with the monitoring port 8222 published, and a secured variant on 4223.
Can NUI decode protobuf and CBOR messages?
Yes, when you supply schemas. The repository includes a Protobuf Message Guide and a CBOR plus CDDL Message Guide under internal/schemas, and the server is started with a cddl-schemas-path argument pointing at a directory of schema files. Without a matching schema, only the text, json and hex views apply to your payload.
Is NUI free and open source?
The repository is published under the Unlicense and the README describes the project as a free and open source NATS management GUI. There is no per-seat pricing and the container image is available from ghcr.io.
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/nats-nui-nui)Was this useful?