Help us shape the future of Go! Take the 2026 Go Developer Survey

nats-tui

command module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: BSD-2-Clause Imports: 7 Imported by: 0

README

nats-tui — a terminal front-end to nats

nats-tui is a Go + bubbletea / huh front-end to nats, the NATS command-line tool. It shows the server a nats context points at as a tree — the JetStream streams with their consumers, the key-value buckets, the object stores, the micro services answering discovery — opens everything in dialog-style editors, and drives nats for every change: each action becomes a plan of nats commands that is previewed, confirmed, run and followed by a re-read of the server. Messages are published, requested and watched live from the same screens. Nothing is ever changed except through nats itself, so the preview is exactly what you could type in a shell.

main screen

It is the sibling of nsc-tui, which does the same for nsc, and shares its look and keys.

go install github.com/olgeni/nats-tui@latest     # or: go build -o nats-tui .
nats-tui                                         # nats's selected context
nats-tui -context prod                           # a named context (nats --context)
nats-tui -s nats://localhost:4222                # a server, no context
nats-tui -mouse                                  # with mouse support (m toggles it at runtime)
nats-tui -refresh 5s                             # re-read the server every 5s (ctrl+r toggles it)
nats-tui -json | jq '.streams[].config.name'     # non-interactive dump; -tree for a text listing
go test ./...                                    # unit tests + server-backed tests (skipped without nats-server)
man ./nats-tui.1                                 # manual page

Main screen

The tree has the context on top, then the streams (a stream expands into its consumers), the key-value buckets, the object stores and the services. The header shows the server, its version and cluster, the round-trip time, the JetStream usage of the account and the credentials in use.

Key Action
↑/↓ j/k pgup/pgdn home/end move
→ / ← / space / * expand / collapse a stream or a section (*: all)
/ filter by name, subject or description (esc clears)
enter details of the entity (a service is also asked for its request statistics); J toggles its raw JSON
e edit the stream, consumer, bucket, object store or context
a add what the row holds: a consumer (on a stream), a key (on a bucket), a file (on an object store), a bucket or store (on their section), a stream elsewhere
A add a stream
d / del delete the stream, consumer, bucket or object store
P purge a stream: everything, one subject, up to a sequence, or all but the last few
v messages of a stream, one page at a time ([ ] page, g jumps to a sequence, f keeps a subject, d deletes a message); on a bucket its keys, on an object store its objects
t subjects held in a stream with their message counts
n next messages of a pull consumer (nats consumer next), acknowledged, nak'ed, terminated or left alone
u pause / resume a consumer
K / O keys of a bucket (put, edit, history, revert, delete, purge, watch) / objects of an object store (put, get, delete, watch); an edited key is written with nats kv update at the revision it was read at
s subscribe live to a stream's subjects, or to what you type
p / R publish a message (nats pub) / send a request and show the reply (nats request)
w watch a bucket or an object store live
E events: JetStream advisories and metrics, server events
I account information
M T L the menus (see below): monitoring, reports, cluster. Each opens a two-row control panel over the tree
C contexts: list, use, select as default, add, edit, copy, delete, validate
S use another context (every command then carries --context)
b / B backup a stream to a directory, or every stream of the account elsewhere / restore a stream or an account backup
y copy a stream's configuration to a new stream, which needs subjects of its own; on a consumer, copy the consumer
x seal a stream or an object store (irreversible)
m toggle the mouse (or start with -mouse): click a row to select it, click it again to open it, wheel scrolls; in editors a click focuses a field, a second click edits or toggles it; hold shift to select text
ctrl+r auto-refresh: re-read the server every 5 seconds, or the -refresh interval, on the main screen, the details and the tables
r re-read the server
h / ? key map / help, q quit

details of a stream

The consumers of a stream and the objects of a store are fetched when the stream is expanded or the store opened, one request each, and kept across reloads, so a server with hundreds of streams opens in the time of one stream list. The counts shown before that come from the stream state.

Sealed streams and paused consumers are shown in yellow; consumers are muted under their stream.

Menus

M, T and L open a menu in the manner of the Lotus 1-2-3 control panel: two rows above the tree, the first holding the items of the level you are in and the second the items of whichever one is highlighted, so the level below is read before it is entered.

 Monitor   Report   Check   Server   Account   Rtt
 Connections  Jetstream  Accounts  Health  Cpu  Mem  Routes  Gateways  Leafnodes  Downgrade

←→ move along a level, the letter picked out in each word chooses that item at once, enter or ↓ opens a group or runs a command, esc or ↑ leaves one level and closes the menu at the top, and the key that opened it closes it from anywhere. So MT is nats rtt and MSL is nats server list, typed as fast as the fingers go. Nothing else reaches the tree while a menu is up, and / stays the filter.

The accelerator is the first letter of a word unless the item names another one, which is how Connections and Cpu keep a letter each.

  • M Monitor — Report (connections, jetstream, accounts, health, cpu, mem, routes, gateways, leafnodes, downgrade), Check, Server (list, info, ping, mappings, account info), Account (info, connections, tls) and Rtt. The server commands need a system account context; rtt and the account commands work with any user. Check begins with This, the nats server check of the selected stream, consumer or bucket, and goes on to jetstream, connection, meta, server, request and credential, the last few behind a small editor for their thresholds.
  • T Reports — Streams, Consumers, Account (the three reports), Find (stream find, consumer find), Gaps, and on a service row Service (info, stats).
  • L Cluster — the commands for the selected stream or consumer first (Stepdown, Peer; Reset, Unpin), then Balance (streams, consumers), Meta (the JetStream meta group: stepdown, peer), Reload, Kick and Purge. Each one is a plan, previewed and confirmed like the others.

Editors

Every entity is edited in the same kind of dialog: labelled fields moved with ↑/↓/tab, enter to edit a text field in place (enter keeps, esc reverts), space for checkboxes, ←/→ for choices, ctrl+s for OK. Lists (subjects, sources, tags, metadata) are comma-separated; metadata is written key=value. Limits are -1 for unlimited; sizes take k/m/g/t (decimal) or kib/mib/gib; durations are 30s, 5m, 2h, 1d, 1w, 1y, blank for none.

the stream editor

Only what changed is passed to nats, and the preview shows the commands:

[1/1] apply the changes (nats shows the difference it applied)
      nats --context prod stream edit ORDERS --max-msgs=500 --deny-purge -f

the plan preview

nats stream edit and nats consumer edit print the difference they applied, which the result screen shows. Some settings are fixed at creation — a stream's storage, a consumer's pull/push mode and its deliver, ack and replay policies — and the plan says so in a note rather than sending a flag the server would refuse. A few nats details the plans know:

  • A new stream or consumer is created with --defaults, so nats never prompts; only what differs from its defaults is passed, plus the storage and the subjects.
  • An unlimited duration is 0 on edit (--max-age=0); -1 is refused there although stream add takes it.
  • --republish-destination needs a --republish-source, so a blank source is sent as >.
  • A consumer with --ack=none cannot carry an ack wait or a pending limit.
  • Deny delete and deny purge cannot be lifted once set, and neither the storage nor the retention of an existing stream can change: the editor accepts the change, the plan drops it and says so in a note.
  • A value or a message body that spans several lines is piped to nats kv put / nats pub --force-stdin rather than passed as an argument. nats kv update reads no stdin, so an edited value is passed as an argument, quoted in the preview.
  • nats server check exits non-zero on a warning or a critical state: that is the result, and the report is shown all the same.
  • B tells a stream backup (a directory holding backup.json) from an account backup (one such directory per stream) and runs nats stream restore or nats account restore accordingly.
  • nats pub --schedule-after (nats 0.4.0) sends the Nats-Schedule header without its @at prefix, which the server refuses (natscli#1719). The flag is only a shorthand for --schedule-at with the current time plus the delay, so the plan does that computation itself and always sends --schedule-at; this works on every version of nats and keeps the preview honest, since no command runs that was not shown. The one cost is that the time is fixed when the plan is built, not when it runs: leave the preview open for a minute and the schedule fires a minute earlier than the delay says. The note on the plan shows the absolute time. Once the fix is released, --schedule-after can be sent directly to versions that have it. Cron schedules take six fields, seconds first.

Messages and live screens

v on a stream reads a page of its messages (an ordered consumer, no state on the server); enter shows one with its headers, JSON indented and binary hex-dumped. a adds a consumer filtered on the subject shown, from the messages table or the subjects table. s subscribes to subjects and shows what arrives, w watches a bucket (every change with its revision, current values first) or an object store, E follows the JetStream advisories, metrics and server events. New entries are followed unless you scroll back; end follows again, / filters by subject or body, c clears, enter opens an entry, p publishes to its subject, esc stops the subscription. The last 5000 entries are kept.

Every table screen (contexts, messages, subjects, keys, history, objects) reads its rows once, when it is opened, so a bucket whose keys have a TTL keeps showing them after they expire. r reads the table again and comes back to the row you were on.

the messages of a stream

a live subscription

A message can also be scheduled instead of sent: the publish editor takes a schedule (once at an RFC3339 time, once after a delay, every interval, or on a cron line), the subject it is published to when the schedule fires, an optional source subject whose last message is sent instead of the body, and a TTL for the fired messages. The stream holding the publish subject must allow message schedules, a stream option that, like per-message TTL, cannot be turned off once on. One schedule lives on each subject: a new one replaces it.

the keys of a bucket

Subscriptions run in the client library over the same connection; what nats sub would print is what the screen shows, without parsing it.

Contexts

A context is a file under ~/.config/nats/context holding a server URL and credentials; nats uses the selected one unless --context is given. nats-tui does the same: -context or S uses one, and every command then carries --context so what runs matches what is shown. C lists them; enter uses one, S makes it the default, e edits it (nats context add on an existing name keeps what is not given), V validates it by connecting. Without any connection — a context that does not answer — the main screen says why and still offers C, S and r.

Non-interactive use

nats-tui -json prints one JSON document with the context, the known contexts, the connection facts (server id, name, version, cluster, max payload, RTT), the JetStream account information, every stream with its configuration, state and consumers, the buckets with their configuration, the object stores with their objects, and the services. -tree prints the same as an indented text listing. Both exit 1 only when the server cannot be reached; a server without JetStream is reported, not an error.

Tests

go test ./...            # everything, a few seconds
go test -v ./cli         # the server-backed tests, verbose (SKIP without nats-server)
go vet ./...

The server-backed tests start a throwaway nats-server -js on a free port under t.TempDir(), point a temporary nats context at it (through XDG_CONFIG_HOME), run the plans the editors would produce through the real nats, read the result back with the client library and compare — the same round trip the TUI makes. They skip themselves when nats-server or nats is not installed. The server runs under a shell holding a pipe from the test binary and is stopped when the pipe closes, so it does not outlive a test that is interrupted, times out or is killed.

Documentation

Overview

Command nats-tui is a terminal user interface for nats, the NATS command-line tool: it shows the streams, consumers, buckets and services of a server as a tree, edits them in dialogs, and drives nats for every change, previewing the commands before running them. Messages are published, requested and watched live from the same screens.

Directories

Path Synopsis
Package cli drives the nats command-line tool and reads the server it points at.
Package cli drives the nats command-line tool and reads the server it points at.
internal
testnats
Package testnats starts a throwaway nats-server for the tests and points a temporary nats context at it, so the server-backed tests never touch a real server or the user's contexts.
Package testnats starts a throwaway nats-server for the tests and points a temporary nats context at it, so the server-backed tests never touch a real server or the user's contexts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL