A real-time, browser-based visualisation of MQTT topic trees. Connect to any broker over WebSocket, subscribe with wildcard support, and watch your topics come alive as an animated force-directed graph.
No backend required — it's a static SPA. Host it anywhere, and the MQTT connection runs directly from the browser.
- Live topic graph — topics appear as nodes in a force-directed layout, sized by message rate and coloured by activity; a one-click "shake" spreads a tangled layout apart
- Wildcard subscriptions — subscribe with
#or+and watch the tree grow in real-time - Payload insights — automatic detection of geo coordinates (map view with movement trails) and image payloads (inline preview), surfaced in a tabbed topic drawer alongside the raw payload and per-topic stats
- Ecosystem awareness — identifies domain objects from known MQTT ecosystems and presents them as a device/entity tree in an Ecosystems panel, with online/offline state, a one-click topic-filter preset per ecosystem, and member nodes coloured by ecosystem on the graph (node body + a thin outline):
- Sparkplug B — edge nodes and devices decoded from protobuf, with BIRTH/DEATH lifecycle and a live metric table
- Home Assistant — MQTT discovery (devices and entities), with follow-on subscriptions that bind live state published in other namespaces
- Homie — the Homie convention (device → node → property), detected by its retained
$-attributes at any base topic (so it also covers Valetudo robots) - LoRaWAN — The Things Network (v3) and ChirpStack: applications → devices, with gateway GPS picked up by the map
- Frigate, Shelly, OwnTracks, OpenDTU — cameras, devices, location trackers (also plotted on the map), and Hoymiles solar inverters, identified structurally from their topic shapes
- Stats dashboard — a right-rail panel with a live throughput chart, noisiest topics, a payload-size histogram, and a per-ecosystem entity breakdown — windowed by previous minute / 5 minutes / since connect
- Expanding side rails — connection and settings on the left, topic / ecosystem / stats detail on the right; the right rail is drag-resizable
- Retained-burst handling — optionally drop the retained flood on connect to keep the graph clean, while still folding ecosystem discovery/config topics into the registry so devices are identified without cluttering the graph
- Fully configurable — tune the graph physics, labels, colours, and behaviour via the UI or a
config.jsonfile - WebMCP support — exposes tools for browser AI agents to query the topic tree (Chrome 146+)
npm install
npm run devOpen the URL shown by Vite (typically http://localhost:5173), enter a WebSocket broker URL (e.g. ws://localhost:9001) and a topic filter, then click Connect.
npm run buildThe output in dist/ is a fully static SPA — deploy it to any static hosting provider. Edit dist/config.json to customise defaults for your deployment without rebuilding.
The app loads config.json on startup to set deployment defaults (broker URL, topic filter, UI preferences, simulation parameters). Users can override any setting in the UI; their choices persist in localStorage.
See docs/configuration.md for the full options reference.
| Layer | Choice |
|---|---|
| Framework | React 18 + TypeScript (strict) |
| Build | Vite 6 |
| Styling | Tailwind CSS v3 |
| Visualisation | D3.js v7 (force simulation, SVG) |
| MQTT | mqtt.js v5 (browser WebSocket, MQTT v5 protocol) |
| Maps | Leaflet + OpenStreetMap tiles |
| State | Zustand v5 |
- Configuration —
config.jsonoptions, precedence rules, broker dropdown setup - Hosting & Deployment — static hosting, mixed content, reverse proxy setup
- Architecture — data flow, how it works, project structure
- WebMCP Integration — browser AI agent tools
- Performance Profiling — automated profiling with Playwright
This project was built with OpenCode and Claude Opus 4 (claude-opus-4-6) by Anthropic.
MIT
