First launch
One command boots two blockchains, a database, the sync node, a batcher, and the frontend. First run downloads the Midnight binaries — give it a few minutes and good Wi-Fi.
1Start the stack
The stack binds all of these on localhost — if any is taken, that process fails to start:
5432 database · 8545/8546 EVM chains ·
9944/8088/6300 Midnight node/indexer/proof server ·
9999 API · 3334 batcher · 8883/9883 MQTT ·
10599 frontend · 4747 orchestrator
The usual offender is 5432: if you have a local PostgreSQL running, stop it first
(mac: brew services stop postgresql · linux: sudo systemctl stop postgresql).
Quick check — this should print nothing:
lsof -i :5432 -i :8545 -i :8546 -i :9944 -i :8088 -i :6300 -i :9999 -i :3334 -i :8883 -i :9883 -i :10599 -i :4747
cd templates/evm-midnight-v2
bun run dev
What the orchestrator launches, in dependency order:
✓ compile-evm-contracts exited successfully ✓ deploy-evm-contracts exited successfully ✓ midnight-contract exited successfully [sync] [APPLY MIGRATION] Block height: 0 | Migration: 000-init.sql [sync] Paima Engine HTTP server running on http://127.0.0.1:9999 ✓ frontend-build exited successfully ● frontend-server running in background
2Poke it
curl -s localhost:9999/api/erc721
[]
Empty array = the sync node is up, the migrations ran, and the API answers.
Then open http://localhost:10599 in your browser — the template's demo dApp should load. If both the curl and the page work, the full stack is alive.
3The orchestrator is your dev loop
During the workshop you'll edit node code and restart just the sync process. Run the stack as a daemon instead:
bunx orchestrator stop # always stop the foreground run first (frees ports)
bunx orchestrator start --background
bunx orchestrator status # what's running
bunx orchestrator logs sync # follow one process's logs
bunx orchestrator restart sync # <- you'll type this a lot in Section C
bunx orchestrator stop # tear everything down
bunx orchestrator stop before starting again — leftover processes keep ports
(8545, 9944, 9999, 10599…) and the next launch fails confusingly.
| Port | What |
|---|---|
| 10599 | frontend |
| 9999 | sync node REST API |
| 3334 | batcher |
| 8545 / 8546 | Hardhat EVM (main / parallel) |
| 9944 / 8088 / 6300 | Midnight node / indexer / proof server |
| 5432 | PGLite (yes — the same port a real Postgres uses) |
| 8883 / 9883 | MQTT events (TCP / WebSocket) |
| 4747 | orchestrator API (when daemonized) |
curl -s localhost:9999/api/erc721 returns [] and
bunx orchestrator status shows sync, batcher, and frontend running.
Stuck? See Troubleshooting.