If you've ever worked with IoT devices over MQTT, you know the tooling situation is... acceptable at best. MQTT Explorer is great for inspecting traffic, but it's a desktop app with no dashboard capabilities. Tools like Node-RED can do dashboards, but they're heavy, opinionated, and not exactly what you'd call a developer tool.
So I built MQTT Dashboard — a self-hostable, single-binary web app that combines an MQTT topic explorer with a fully customizable drag-and-drop dashboard. Here's why I built it, what's inside, and how you can run it in 30 seconds.
The Problem
Existing MQTT tools tend to fall into one of two buckets:
- Pure clients (like MQTT Explorer, MQTT.fx): great for debugging, no persistence, no dashboards.
- Full platforms (like Node-RED, Home Assistant): powerful, but heavy and not focused on the developer debugging workflow.
What I wanted was something in between — a lightweight self-hosted tool where I could connect to a broker, explore topics in real time, and build a control panel for testing my device without switching apps.
What It Does
🧩 Drag & Drop Dashboard
The dashboard is built around a grid layout engine (react-grid-layout). Panels are resizable and reorderable. You configure them per broker/topic, and the layout is persisted in SQLite so it's there when you come back.
Functional panels available:
| Panel | What it does |
|---|---|
| Button | One-click publish a preset payload to a topic |
| Input | Type and send ad-hoc messages to any topic |
| Log | Live message stream with history and wildcard subscriptions |
| Cron | Scheduled publishing with a visual cron builder and countdown |
| Stats | Topic activity chart with configurable time window |
Visual panels:
| Panel | What it does |
|---|---|
| Image | Display an image from URL or file |
| Separator | Horizontal/vertical divider |
| Text | Markdown text for documenting your dashboard |
🌳 Topic Explorer
The topic explorer lets you browse a real-time tree of all topics active on the broker. Subscriptions support + (single-level) and # (multi-level) MQTT wildcards. Message history is persistent with configurable retention.
🔌 Multi-Broker Support
You can connect to multiple MQTT brokers simultaneously and switch between them from a single interface. Each broker can be configured with:
- Plain TCP or TLS/SSL
- Username & password authentication
- Client certificate authentication (mTLS)
- QoS and retain flags
Architecture
The whole thing ships as a single Go binary that embeds the compiled React frontend. No separate web server needed.
┌──────────────────────────┐ ┌──────────────────────┐
│ React Frontend (SPA) │◄──WS──► │ Go Backend │
│ Vite + Tailwind + │◄──API─► │ Single Binary │
│ DaisyUI │ │ │
└──────────────────────────┘ └──────────┬───────────┘
│
┌──────────┴───────────┐
│ │
┌──────▼──────┐ ┌──────────▼──────────┐
│ SQLite │ │ MQTT Brokers (N) │
│ (layouts, │ │ TCP / TLS / Auth │
│ configs, │ └─────────────────────┘
│ history) │
└─────────────┘
- The Go backend uses Eclipse paho.mqtt.golang for MQTT connections, SQLite for persistence, gocron for the scheduled publishing feature, and WebSockets for pushing live data to the frontend.
- The React frontend is built with Vite + TypeScript + Tailwind + DaisyUI, and uses react-grid-layout for the dashboard grid.
In production, the Go binary serves the embedded React build directly — no Vite dev server in the loop. Everything runs on a single port (:8080).
Tech stack at a glance:
| Layer | Technology |
|---|---|
| Frontend | React, Vite, TypeScript, Tailwind CSS, DaisyUI |
| Grid engine | react-grid-layout |
| Backend | Go (Golang) |
| MQTT lib | Eclipse paho.mqtt.golang |
| Database | SQLite (embedded) |
| Scheduling | gocron |
| Realtime | WebSocket |
| Container | Docker (Alpine) |
Getting Started
Option 1: Docker Compose (Recommended)
services:
mqtt-dashboard:
image: ghcr.io/jmischler72/mqtt-dashboard:latest
container_name: mqtt-dashboard
ports:
- "8080:8080"
volumes:
- data_volume:/app/data
volumes:
data_volume:
docker compose up -d
Done. Open http://localhost:8080.
Option 2: Docker Command
docker run -d \
--restart=always \
-p 8080:8080 \
-v mqtt-dashboard-data:/app/data \
--name mqtt-dashboard \
ghcr.io/jmischler72/mqtt-dashboard:latest
Option 3: Build from Source
Requirements: Go 1.22+, Node.js 20+
git clone https://github.com/jmischler72/mqtt-dashboard.git
cd mqtt-dashboard
# Build frontend
cd frontend && npm ci && npm run build && cd ..
# Build backend (embeds the compiled frontend)
cd backend
cp -r ../frontend/dist ./dist
go build -o mqtt-dashboard .
./mqtt-dashboard
What's Next
A few things I'm working on or thinking about:
- Custom panels — let users build and share their own panel types
- More configuration options for built-in panels
The full roadmap is in TODO.md and the docs/PRD/ folder.
Wrapping Up
This project was heavily inspired by MQTT Explorer — if you haven't used it, check it out. MQTT Dashboard tries to extend that exploration-focused experience with persistence and a customizable control interface, all packaged in a self-hostable single binary.
If you find it useful, a ⭐ on GitHub goes a long way. And if you run into bugs or have feature ideas, issues and PRs are very welcome!
Built with Go + React · GPL-3.0 · github.com/jmischler72/mqtt-dashboard


Top comments (0)