mqttui gives you a terminal UI and a scriptable MQTT client
Subscribe to a MQTT topic or publish something quickly from the terminal
At a glance
- What is it?
- mqttui is a Rust command line tool for MQTT that can watch topics in a ratatui interface, publish from stdin, log to stdout, read a single payload for use in a shell variable, and clear retained messages. It is GPL-3.0 licensed, packaged for the major Linux package managers, and released as prebuilt binaries for five architectures.
- Who is it for?
- mqttui suits someone who needs to look at MQTT traffic or fire a message at a topic during development, since the read-one and log subcommands drop into shell scripts and the TUI covers the browse-and-publish case without a browser. It is the wrong tool if you need the breadth of a full MQTT client library, because the README is explicit that it will not be as feature rich as the HiveMQ CLI approach.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A topic watcher that opens in a terminal
mqttui is described as a way to subscribe to a MQTT topic or publish something quickly from the terminal, and the default behaviour is to open an interactive terminal UI.
# Subscribe to everything (#)
mqttui
# Subscribe to topic
mqttui "topic"
# Subscribe to topic with a specific host (default is mqtt://localhost)
mqttui --broker "mqtt://test.mosquitto.org" "hello/world"The default broker is mqtt://localhost, which is why the broker flag is needed for anything else, and the topic argument accepts MQTT wildcards, since the first example subscribes to everything with a hash.
The interface itself is built on ratatui with crossterm, and the topic tree is a tui-tree-widget, so topics are shown as a hierarchy rather than a flat list. That structure is what makes the retained message cleanup feature possible, since you select a node and act on it.
For a project with no homepage and a repository whose topics include mqtt-explorer and mqtt-topic, the terminal interface is the whole product rather than one feature among several.
Publishing from a shell pipeline
The publish subcommand is the part that fits into existing shell habits rather than an interactive session.
mqttui publish "hello" "world"
mqttui publish --retain "foo/bar" "Banana?"The first argument is the topic and the second is the payload. The --retain flag sets the retained message flag, which is what makes a message persist on the broker until it is replaced or cleared.
Stdin is supported, which is what turns it into a pipeline tool:
mqttui publish "foo/bar" </etc/hostname
# or other things
cowsay "I was here" | mqttui publish "foo/bar"So a file or any command's output can become the payload of a message, with no temporary file and no interactive prompt. The README's own example with cowsay is not serious about the payload, but it makes the point that the tool does not care what the bytes are.
The rest of the command line surface is documented through mqttui publish --help, which is where the environment variables are listed as well.
Log to stdout and read-one for scripts
The log subcommand prints each received message as a line, and the format is fixed enough to grep:
$ mqttui log "espHome-co2/sensor/#" "espHome-test/sensor/temperature/state"
RETAINED espHome-co2/sensor/rssi/state QoS:AtMostOnce Payload( 6): -80.09
RETAINED espHome-co2/sensor/co2/state QoS:AtMostOnce Payload( 5): 450.8
12:10:06.650 espHome-test/sensor/temperature/state QoS:AtMostOnce Payload( 6): 10.454
12:10:39.606 espHome-co2/sensor/co2/state QoS:AtMostOnce Payload( 5): 432.5Each line carries a timestamp, the RETAINED marker where it applies, the topic, the QoS level and the payload with its length. Multiple topics can be given:
# Subscribe to topic
mqttui log "topic"
# Multiple topics
mqttui log "topic1" "topic2"The read-one subcommand is the one built for shell scripting, and it separates stdout from stderr so the payload can be captured cleanly:
# Print the first received message to stdout and the topic to stderr
mqttui read-one room/temp
# Save the payload to a bash variable to use it
temp=$(mqttui read-one room/temp)
echo "The temperature is $temp right now"There is also a --ignore-retained flag, which waits for a fresh message instead of returning the retained one that is already sitting on the broker. The README's second example uses it to wait for breaking news rather than re-reading the last known value:
temp=$(mqttui read-one --ignore-retained room/temp)
echo "Breaking news: We just received an updated temperature of $temp"That distinction matters whenever a stale retained value would be silently treated as current.
Clearing retained messages from the tree
Retained messages accumulate on a broker and are hard to get rid of without knowing which topics hold them, and mqttui treats that as a first class operation.
In the interactive TUI, pressing Delete or Backspace on a topic opens a cleaning dialog for that part of the tree. The same thing is available as a subcommand:
# Clean the topic
mqttui clean-retained "topic"
# Clean the topic tree below
mqttui clean-retained "topic/#"The output shows what was removed and how much:
$ mqttui publish --retain "hello" "world"
$ mqttui clean-retained "hello"
RETAINED hello QoS:AtLeastOnce Payload( 5): world
Cleaned 1 topicsNote that the cleaned message reports QoS:AtLeastOnce, which is a QoS the retained publish in that example did not ask for. The README does not explain that difference, so the QoS column in the output should be read as what the broker reports rather than as a setting the tool controls.
Installing: three routes, and a libc caveat
The README lists three install routes in order of preference: a package manager, a prebuilt binary, or building from source.
The packaged route covers the common distributions:
apk add mqttuipacman -S mqttuibrew install mqttuiThose are Alpine, Arch Linux and Homebrew for Mac or Linux, and the README also carries a repology badge tracking which repositories carry the package.
The prebuilt route downloads a zip named like mqttui-<version>-<architecture>-<platform>.zip from the releases page. The CPU architectures covered are x86_64 for AMD and Intel, aarch64 for 64 bit ARMv8, riscv64gc for 64 bit RISC-V, armv7 for 32 bit ARMv7 and arm for 32 bit ARMv6. Debian and Ubuntu users get a .deb installed with dpkg, Red Hat and CentOS users get an .rpm installed with rpm, and other UNIX systems get plain tarballs whose binary has to be placed somewhere on your path, with ~/bin, ~/.local/bin and /usr/local/bin given as common locations. Windows users take a mqttui-<version>-<arch>-pc-windows-msvc.zip.
There is one constraint worth checking early. The Linux binaries are built for glibc based systems, so for other libc or musl systems like Alpine Linux you need to compile from source or install from a repository. Since Alpine is one of the packaged targets, this only bites if you are using the tarball rather than the apk.
Building from source means cloning the repository and running cargo install --path ., and the manifest requires Rust 1.88 with edition 2024.
Configuration through environment variables
The tool can be configured through environment variables, and the README's own suggestion is the one worth copying:
export MQTTUI_BROKER=mqtt://pi-home.local
# Use the command without specifying the broker every time
mqttui "topic"Setting a default broker removes the need to pass --broker on every invocation, which matters most in scripts where the flag would otherwise be repeated on every line.
The README does not enumerate the variable names beyond MQTTUI_BROKER, and it points at the --help output for the environment variables to be set. That is a fair arrangement given that the clap derive setup enables the env feature, but it does mean the authoritative list lives in the built binary rather than in the documentation, so anyone scripting against a specific variable name should confirm it with mqttui --help first.
The Cargo manifest also shows clap_complete and clap_mangen in the build dependencies, so shell completion and man page generation are part of the build rather than something maintained by hand.
How the author positions it against other clients
The README has a History and Alternatives section that states the trade-offs without pretending the tool is the most capable option.
The complaint about existing view-it-now or publish-it-now projects is that they are always quite bulky and not that fast. The specific comparison given is thomasnordquist/MQTT-Explorer, which the author used before mqttui because it has a great overview of what is going on, a small topic based history and a sorted main view, but while it is running it is eating up a lot of resources.
For publishing from the command line, the alternative is hivemq/mqtt-cli, described as feature rich but taking some time to do its job and not as easy to use because it has a lot of flags to specify. And mosquitto_sub and mosquitto_pub, which come bundled with Mosquitto, are called a bit bulky to use.
The conclusion the author draws is honest about the trade. It won't be as feature rich as something like the HiveMQ CLI approach, but it aims at being easy to use and fast. That is the line to hold when choosing: mqttui is a fast, small front end for the two operations you do most, not a replacement for a full client.
The Rust side backs the smallness claim up in a way. The manifest sets codegen-units to 1 and enables lto for release builds, forbids unsafe code outright, and turns on the pedantic and nursery clippy lint groups. The MQTT work is done by rumqttc with websocket support, and TLS is handled by rustls with the rustls-platform-verifier crate, which delegates certificate verification to the platform.
Editorial conclusion
mqttui suits someone who needs to look at MQTT traffic or fire a message at a topic during development, since the read-one and log subcommands drop into shell scripts and the TUI covers the browse-and-publish case without a browser. It is the wrong tool if you need the breadth of a full MQTT client library, because the README is explicit that it will not be as feature rich as the HiveMQ CLI approach. Before adopting it, set MQTTUI_BROKER so the broker is not repeated on every invocation, and check the glibc note if you run on musl based systems such as Alpine Linux, where the tarball binaries will not work and you need to install from source or from the package repository.
Frequently asked questions
How do I install mqttui on Linux?
Use your package manager where the project is packaged, with apk add mqttui on Alpine, pacman -S mqttui on Arch Linux or brew install mqttui through Homebrew. Otherwise download a prebuilt archive from the releases page and install the .deb with dpkg, the .rpm with rpm, or extract the tarball binary onto your path. The Linux tarball binaries are built for glibc, so musl systems such as Alpine need a source build instead.
How do I read a single MQTT payload into a shell variable with mqttui?
Use the read-one subcommand, which prints the first received message to stdout and the topic to stderr, so temp=$(mqttui read-one room/temp) captures only the payload. Add --ignore-retained to wait for a fresh message instead of returning the retained value already on the broker.
How do I delete retained messages in mqttui?
In the interactive terminal UI, press Delete or Backspace on a topic to open the cleaning dialog. From the command line, mqttui clean-retained "topic" clears one topic and mqttui clean-retained "topic/#" clears the topic tree below it, printing how many topics were cleaned.
Does mqttui support setting a default broker?
Yes, through environment variables. The README shows export MQTTUI_BROKER=mqtt://pi-home.local, after which mqttui "topic" uses that broker without the --broker flag. The README points at the --help output for the full list of environment variables that can be set.
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/edjopato-mqttui)Was this useful?