MIDI over HTTP β simple, powerful, and cross-platform.
Added quite a few enhancements and tools for troubleshooting network midi issues in complex multi system setups.
Midi Relay Hub lets you send and receive MIDI messages across a network using JSON-based HTTP requests. Built for AV and stage production (Church, Concerts, stage shows, plays, etc), automation, and integration with tools like streamdeck, Bitfocus Companion and n8n.
πΉ Originally forked from midi-relay (Joseph Adams) and expanded significantly.
-
HTTP API β Send MIDI messages via REST endpoints (JSON)
-
Real-time Logging β Live WebSocket stream of all MIDI traffic
-
Triggers β React to incoming MIDI with HTTP webhooks, scripts, or automation
-
Profiles β Save/load trigger configurations for different events
-
Test Button β Validate your webhook URLs before going live
-
Cross-platform β Runs on Windows/Linux; macOS from source (packaging/signing currently disabled)
-
Companion API URL Builder β Helps construct URLs to send to companion for triggers and testing
-
Surfaces (Preview + Embed) β View registered button surfaces and embed a Companion emulator URL as a fallback viewer
- ScreenDeck Settings (WIP) β Configure Companion Satellite host/port and define ScreenDeck devices
- Optional mDNS β Runs even if
mdns-jsis not installed (discovery is optional) - caused errors and dependency vulnerabilities as of Jan-2026
- Download the latest release from Releases
- On Windows, run the installer
.exe - MIDI ports are scanned automatically on startup
- Access the web UI at
http://127.0.0.1:8090(default; configurable viaapiPort)
Note: macOS packaging/signing is currently disabled until an Apple Developer ID is available.
# Clone the repo
git clone https://github.com/radicaldo/midi-relay-hub.git
cd midi-relay-hub
# Install dependencies
npm install
# Start the app
npm startnpm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # With coverage reportThe HTTP API allows integration with any system that can make HTTP requests.
Send a Note On:
curl -X POST http://localhost:4000/sendmidi \
-H "Content-Type: application/json" \
-d '{"midiport":"My MIDI Device","midicommand":"noteon","channel":0,"note":60,"velocity":127}'Get MIDI Ports:
curl http://localhost:4000/midi_outputs
curl http://localhost:4000/midi_inputsView Live Log:
curl http://localhost:4000/logGet ScreenDeck integration settings:
curl http://127.0.0.1:8090/integrations/screendeckUpdate ScreenDeck integration settings (emulator URL / host / port / devices):
curl -X POST http://127.0.0.1:8090/integrations/screendeck \
-H "Content-Type: application/json" \
-d '{"emulatorUrl":"http://127.0.0.1:8000/emulator/"}'List currently-registered surfaces (snapshot):
curl http://127.0.0.1:8090/surfacesTriggers let you react to incoming MIDI messages. When a matching MIDI message is received, the trigger fires an action:
| Action Type | Description |
|---|---|
http |
Send HTTP GET/POST/PUT/PATCH/DELETE to a URL |
midi |
Send a MIDI message to another port |
# List all triggers
curl http://localhost:4000/triggers
# Add a trigger
curl -X POST http://localhost:4000/trigger/add \
-H "Content-Type: application/json" \
-d '{"midicommand":"noteon","channel":0,"note":60,"actiontype":"http","url":"http://your-webhook.com"}'
# Test a trigger
curl -X POST http://localhost:4000/trigger/test \
-H "Content-Type: application/json" \
-d '{"id":"trigger-abc123"}'Save and load different trigger configurations:
# List profiles
curl http://localhost:4000/profiles
# Save current triggers as a profile
curl -X POST http://localhost:4000/profiles/save \
-H "Content-Type: application/json" \
-d '{"name":"Sunday Service"}'
# Load a profile
curl -X POST http://localhost:4000/profiles/load \
-H "Content-Type: application/json" \
-d '{"name":"Sunday Service"}'The app stores configuration using electron-store. Settings include:
| Setting | Default | Description |
|---|---|---|
apiPort |
8090 |
HTTP server port |
allowControl |
true |
Allow sending MIDI via API |
logLevel |
info |
Log verbosity (debug/info/warn/error) |
httpTimeout |
5000 |
Timeout for HTTP triggers (ms) |
These settings are stored under the screenDeck key:
| Setting | Default | Description |
|---|---|---|
screenDeck.companionHost |
127.0.0.1 |
Companion Satellite host/IP |
screenDeck.companionPort |
16622 |
Companion Satellite port |
screenDeck.emulatorUrl |
"" |
Optional Companion emulator URL for iframe embed in Surfaces |
screenDeck.devices |
[] |
Virtual deck definitions (cols/rows/bitmap/bg/etc) |
Note: the ScreenDeck settings UI exists, but the actual Satellite connection/rendering is still pending.
The Surfaces tab is intended to display βbutton surfacesβ (virtual or physical) across your network.
- You can embed a remote Companion emulator URL (useful as a last-resort viewer)
- You can also register custom surfaces via Socket.IO (see
surface_registerin the UI tip)
- Create a webhook trigger in n8n
- Add a trigger in Midi Relay Hub pointing to your n8n webhook URL
- Incoming MIDI will now trigger your n8n workflow
Use the midi-relay Companion module to send MIDI from Companion buttons or from Midi Relay Hub you can control companion or remote streamdecks.
βββ index.js # Electron main process
βββ api.js # Express HTTP API
βββ midi.js # MIDI port management & triggers
βββ util.js # Utilities and validation exports
βββ config.js # Electron-store configuration
βββ logger.js # Logging utility
βββ static/ # Web UI assets
βββ __tests__/ # Jest test suite
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Ensure
npm testpasses - Submit a pull request
This project stands on the shoulders of giants. Huge thanks to:
| Project | Author | Why It's Awesome |
|---|---|---|
| midi-relay | Joseph Adams | The original project this fork is built on. Clean, simple MIDI-over-HTTP that just works. |
| JZZ.js | Sema / jazz-soft | Actively maintained MIDI library with MIDI 2.0 support. The backbone of this app. |
| Electron | GitHub/OpenJS Foundation | Cross-platform desktop apps with web tech |
| Express | TJ Holowaychuk & community | Fast, unopinionated web framework |
| Socket.IO | Guillermo Rauch | Real-time bidirectional event-based communication |
| Project | Description |
|---|---|
| Bitfocus Companion | Stream Deck software for broadcast/production β has a midi-relay module |
| n8n | Workflow automation that pairs perfectly with MIDI triggers |
| Lodash | Utility functions that make JS less painful |
| Tool | Purpose |
|---|---|
| Jest | Testing framework |
| Husky | Git hooks made easy |
| Prettier | Code formatting |
Want to stay informed when upstream projects release updates?
- Go to any repo (e.g., JZZ or midi-relay)
- Click the Watch button (top right)
- Select Custom β Check Releases
- You'll get notified when new versions are published
This repo uses GitHub's Dependabot to automatically create PRs when dependencies have updates. Check .github/dependabot.yml for configuration.
# Check for outdated packages
npm outdated
# Update to latest (minor/patch)
npm update
# Check for major version updates
npx npm-check-updatesMIT License Forked and extended by Radicaldo. Midi Relay Originally created by Joseph Adams.