Run a demo from stack to dashboard
[⏱️ ~15 min] Run a browser dashboard demo on top of the stack with React and MDK UI components
Get started · 3 of 3 · Build a live dashboard
If ORK, worker, manager, or thing are unfamiliar, read terminology.md first.
Overview
This is rung 3 of the Get started ladder: build. It puts a real browser dashboard on top of the stack you already know, using
the mdk-site-monitor example.
What you'll have at the end:
- The same mock Whatsminer M56S stack from rung 2, fronted by an App Node REST API on
:3000 - A React dashboard on
:3030— total hashrate, total power, and active device count as metric cards, a live hashrate chart, and a per-device breakdown - The dashboard polling App Node every 5 seconds, built entirely from MDK UI components (
MetricCard,HashRateLineChart,Typography, ...)
Same shape as rungs 1 and 2: underneath, the stack still boots with getOrk(), startWorker(), and registerThing(), and the device is the same
Whatsminer M56S mock as rung 2. What's new is two layers on top — App Node translating MDK Protocol to REST, and a Vite React UI
consuming that REST.
Prerequisites
- Node.js >=24 (LTS)
- npm >=11
The stack starts an ORK whose control plane is peer-to-peer over a Hyperswarm DHT, so it needs outbound network access. Without it the stack stalls at startup while the ORK tries to reach DHT bootstrap nodes. See how workers connect for the ORK/DHT mechanics.
Clone and install the stack
1.1 Clone the repo
git clone git@github.com:tetherto/mdk.git
cd mdk1.2 Install dependencies
backend/core/install-packages.sh ci
backend/workers/install-packages.sh ciBuild the UI packages (one time)
The dashboard imports pre-built MDK UI packages from ui. Build them once:
cd ui
npm install
npm run build
cd -This is the slow step — it compiles the UI workspace. You only do it once; re-running the dashboard later skips straight to the next step.
Install the dashboard's dependencies
cd examples/e2e/ui
npm install
cd -Start everything
start.js is an interactive launcher. From the repo root:
node examples/e2e/start.jsIt prints the available services and a prompt. Type start all to launch the backend and UI together:
mdk> start allThis starts:
- App Node (
server.js --app-node) — ORK + mock Whatsminer + a REST API onhttp://localhost:3000, innoAuthmode - UI — a Vite dev server on
http://localhost:3030, launched withVITE_NO_AUTH=trueso it skips the login screen
Wait a few seconds for both to come up, then open:
http://localhost:3030You'll see the dashboard populate within ~5 seconds (its first poll), then update live.
Other launcher commands:
status — show running services and their URLs
stop [ork|app-node|ui|all] — stop a service (default: all)
start [ork|app-node|ui|all] — start a service (default: all)
help — show usage
exit — stop everything and quitstart all runs App Node in noAuth mode for development convenience. Do not expose port 3000 outside localhost.
What you'll see
The page renders three metric cards (Total Hashrate in TH/s, Total Power in W, Active Devices), a live hashrate line chart that grows as new data points
arrive, and a per-device table. All of it comes from @tetherto/mdk-react-devkit components driven by the @tetherto/mdk-react-adapter data hooks —
no hand-rolled UI. See SiteHashratePage.tsx for the page source.
Cleanup
At the launcher prompt:
mdk> exitexit stops App Node, the mock, ORK, and the UI dev server. server.js leaves data under os.tmpdir()/mdk/ — safe to ignore, or remove with:
rm -rf "$TMPDIR/mdk" /tmp/mdkAdd real auth (Google OAuth)
The start all shortcut above runs in noAuth mode so you can see the dashboard immediately. To exercise the real authentication flow — a Google
sign-in that issues a bearer token the dashboard sends on every request — configure OAuth and start the services without the noAuth shortcut.
1. Create a Google OAuth 2.0 client
- Go to Google Cloud Console API credentials
- Create an OAuth 2.0 Client ID (type: Web application)
- Add to Authorized redirect URIs:
http://localhost:3000/oauth/google/callback - Add to Authorized JavaScript origins:
http://localhost:3030 - Copy the Client ID and Client Secret
2. Configure App Node
Edit backend/core/app-node/config/facs/httpd-oauth2.config.json (copy from .example if it doesn't exist) and fill in your client ID and secret:
{
"h0": {
"method": "google",
"credentials": { "client": { "id": "<YOUR_CLIENT_ID>", "secret": "<YOUR_CLIENT_SECRET>" } },
"startRedirectPath": "/oauth/google",
"callbackUri": "http://localhost:3000/oauth/google/callback",
"callbackUriUI": "http://localhost:3000",
"users": []
}
}3. Set yourself as super-admin
In backend/core/app-node/config/facs/auth.config.json, set superAdmin to your Google account email:
{ "a0": { "superAdmin": "you@example.com" } }4. Run with auth
Start App Node and the UI without the VITE_NO_AUTH shortcut (run them directly rather than via start all), open http://localhost:3030, click Sign in with Google, and authorise with the super-admin email. The dashboard then shows live data behind the token.
For the full setup, see the example's README.md.
Continue
Previous: 2. Control devices from the CLI
You've climbed the whole ladder: observed a stack, driven it from a CLI, and built a live UI on it.
Go deeper
- The full example, including the OAuth setup and how to add a new data panel —
examples/e2e/README.md - The MDK UI toolkit (components, hooks, theming) —
ui/README.md - Run a full site (5 workers, 26 devices) —
backend/core/examples/mdk-site/site.js - Read all runnable examples in one place —
backend/core/examples/README.md