termqtt is a terminal-based MQTT monitoring and debugging app built with Bun + OpenTUI. It subscribes to your configured root topic, organizes messages in a three-pane layout, and lets you inspect, filter, watch, favorite, and publish JSON payloads without leaving the terminal.
- Live MQTT monitoring with connection status, search, and exclude filters.
- Two-row UI: Topics + Payload + Details (top), Favourites + Watchlist (bottom).
- JSON flattening for quick scanning with type-aware coloring.
- Inline editing and publishing for existing messages or new payloads.
- Saved messages library for quick re-use.
- Persistent broker config, exclude filters, watchlist, favourites, and saved messages.
Each release ships a single zip per OS/arch that contains the binary and the TreeSitter worker.
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/headcrest/termqtt/main/scripts/install.sh | bash -s -- headcrest/termqttWindows (PowerShell):
iwr https://raw.githubusercontent.com/headcrest/termqtt/main/scripts/install.ps1 -UseBasicParsing -OutFile install.ps1
./install.ps1 -Repo headcrest/termqttOn first run (or any time later), press b to configure the broker.
Configuration is saved under $XDG_CONFIG_HOME/termqtt (or ~/.config/termqtt).
On Windows it uses %APPDATA%\termqtt.
termqtt --help
termqtt --version
termqtt -b localhost -P 1883 -r sensors/#
termqtt --broker mqtt.example.com --tls --user alice --password secret -r devices/#Flags:
-h,--helpshow help-v,--versionshow version--upgradeupgrade to latest release (prompted)-y,--yesskip confirmation prompts--clear-storage [glob]delete local config files (with prompt)-b,--brokerbroker host-P,--portbroker port-u,--userusername-w,--passwordpassword-t,--tlsenable TLS-r,--root-topicroot topic (subscribe filter)
- Top row: Topics (left), Payload (middle), Details (right).
- Bottom row: Favourites (left), Watchlist (right).
- Select a topic in the Topics pane to view its payload and details.
- Press
spaceon a topic to toggle it as a favourite. - Press
spaceon a payload key to add/remove it from the watchlist. - Use
/to search topics andfto manage exclude filters. - Press
ein Details to edit and publish the selected message. - Press
nanywhere to create and publish a new message.
/start search- Type to filter topics (live)
Esccancel
Exclude filters hide topics when their pattern matches (defaults: read, data, config).
fopen the exclude filters dialogspacetoggle exclude for the selected filteraadd a new exclude filtereedit the selected filterddelete the selected filterEnterapply filtersEsccancel
Tab/Shift+Tabcycle panes1Topics,2Payload,3Details,4Favourites,5Watchlistj/kmove selectionh/lcollapse/expand tree in Topicsbopen broker configuration/search topicsfexclude filtersnpublish new?open help dialogqquit
Topics pane:
spacetoggle favourite for selected topic
Favourites pane:
spaceremove favouriterrename favourite
Payload pane:
spacetoggle watchlist for selected key
Watchlist pane:
spaceremove watchlist entry
Details pane:
eedit selected message and publish
Tab/Shift+Tabmove between fields and key/value columnsj/kmove between rowsCtrl+nadd rowCtrl+ddelete row (orCtrl+Backspace)Ctrl+kclear current fieldCtrl+xclear all fieldsCtrl+rtoggleread/writein topicCtrl+ssave message to the libraryCtrl+lfocus saved messages listEnterpublish (if valid)Escclose
Same controls as Edit dialog.
j/kmove selectionEnterload saved message into the editordorDeleteremove saved message
Tab/Shift+Tabmove between fieldsEntersave and reconnectEsccancel
termqtt stores local data under $XDG_CONFIG_HOME/termqtt (or ~/.config/termqtt).
On Windows it uses %APPDATA%\termqtt.
termqtt_broker.jsonbroker configuration (global)broker_<host>_<port>_termqtt_watchlist.jsonwatchlist entriesbroker_<host>_<port>_termqtt_favourites.jsonfavourite topicsbroker_<host>_<port>_termqtt_saved_messages.jsonsaved messages librarybroker_<host>_<port>_termqtt_filters.jsonexclude filters
- Terminal not restored: run
reset. - Can’t connect: press
b, verify host/port/credentials, and confirm broker is running. - Watchlist or favourites not saving: check file permissions in the config directory.
Please open a GitHub issue with:
- Steps to reproduce
- Expected vs actual behavior
- Your OS, terminal, and termqtt version
- Any relevant logs or screenshots
Pull requests are welcome.
- Fork the repo and create a feature branch.
- Make your changes with tests where appropriate.
- Run
bun testlocally. - Open a PR describing the change and reasoning.
- CLI UI built with
@opentui/reactand@opentui/core index.tsxboots the CLI renderer and renders<App />src/app/App.tsxcomposes panes, dialogs, and hooks- State lives in
src/state.tsand updates viasrc/app/reducer.ts - MQTT lifecycle handled by
src/mqtt.tsthroughsrc/hooks/useMqtt.ts - Selectors in
src/app/selectors.tsshape state for display
- App starts in
index.tsxand renders<App />. useMqttcreates anMqttManagerwith callbacks that dispatch reducer actions.MqttManager.connect()establishes the MQTT connection and subscribes to the configured filter.- Incoming MQTT messages dispatch
action: "message". - The reducer stores the message, updates topic lists and counters.
- Selectors derive tree entries, payload entries, status text, and details content.
- Panes render from derived data; status bar reflects connection + subscription info.
- Keyboard shortcuts and dialogs dispatch state updates that feed back into the same flow.
flowchart TD
A[index.tsx] --> B[createCliRenderer + createRoot]
B --> C[App]
C --> D[useMqtt]
D --> E[MqttManager]
E -->|connect/subscribe| F[MQTT broker]
F -->|message| E
E -->|dispatch message/status/subscription| G[reducer]
G --> H[AppState]
H --> I[selectors]
I --> J[PaneLayout + StatusBar]
C --> K[DialogHost]
C --> L[useKeyboardShortcuts]
J --> H
K --> H
L --> H
Install dependencies:
bun installRun:
bun run index.tsxBuild compiled binary:
bun build --compile ./index.tsx --outfile dist/termqttPackage zip (local):
bun run scripts/package.tsMIT
