An open-source, configurable multi-function display (MFD) panel builder for space sims and flight games. Design custom button layouts on your desktop, then use any phone or tablet as a touch-screen control panel over your local network.
Built with Tauri, React, and Rust.
- Visual drag-and-drop editor: place buttons, sliders, labels, panels, carousels, and images on a canvas with snap guides and alignment tools
- Action sequences: bind multi-step macros to a single button press (key combos, delays, sounds)
- Mobile client: any device with a browser becomes a control panel (served over your local network)
- Screen effects: scanlines, LCD grid, phosphor glow, vignette, flicker, chromatic aberration, noise
- Elite Dangerous integration: journal file watching with live status events (WIP)
- Input backends: VJoy (Windows), evdev virtual device (Linux)
- Auto-update: checks GitHub Releases on startup and prompts to install
After installation, launch the app and create a new screen set. Use the editor to design your layout, then connect your mobile device to the same Wi-Fi network and open the provided URL (or scan the QR code) to access your custom control panel.
Important Note for Windows Users: vJoy is required for handling inputs
- Node.js 20+
- Rust (stable)
- Tauri CLI prerequisites for your platform
yarn install
yarn tauri devThis starts both the Vite dev server (frontend hot-reload) and the Tauri backend.
yarn tauri buildProduces platform-specific installers in src-tauri/target/release/bundle/.
AstroMFD/
├── src/ # Desktop editor (React + Konva)
├── mobile-client/ # Mobile touch client (React, served via HTTP)
├── shared/ # Shared TypeScript types
├── src-tauri/ # Rust backend
│ └── src/
│ ├── commands/ # Tauri IPC commands
│ ├── input/ # Input device abstraction (VJoy/evdev/mock)
│ ├── journal/ # Elite Dangerous journal watcher
│ ├── widget/ # Widget/screen model + serialization
│ └── lib.rs # App setup, axum server, plugin registration
└── sfx/ # Bundled sound effects
- The desktop app runs an HTTP + WebSocket server on a configurable port (default 11011)
- Mobile devices connect via browser to
http://<your-ip>:<port> - Button presses on the mobile client are sent over WebSocket
- The Rust backend translates them into virtual joystick inputs (vJoy on windows, evdev on linux) or keyboard events (linux only)
Settings are accessible via the gear icon on the home screen:
| Setting | Description | Default |
|---|---|---|
| Mobile Client Port | Port the mobile server listens on | 11011 |
| Journal Path | Elite Dangerous journal directory | Auto-detect |
| VJoy Device ID | Virtual joystick device number (Windows only) | 2 |
Settings are stored in ~/.local/share/AstroMFD/settings.json (Linux/macOS) or the equivalent AppData/Local path on Windows. Changes require an app restart.
Releases are built via GitHub Actions when a version tag is pushed:
# Bump version in tauri.conf.json and package.json, then:
git tag v0.2.0
git push origin v0.2.0The workflow builds for macOS (ARM + Intel), Windows, and Linux, then creates a draft GitHub Release. Review and publish to make it available to the auto-updater.
To build a standalone version without the auto-update plugin, pass --no-default-features:
yarn tauri build -- --no-default-featuresRust:
tauri- app framework, IPC, window managementaxum- HTTP/WebSocket server for the mobile clienttokio- async runtimerodio- audio playback for action soundsserde/serde_json- serializationfont-kit- system font enumerationnotify- filesystem watching (journal)rfd- native file dialogslocal-ip-address- LAN IP for QR code displaytauri-plugin-updater- auto-update from GitHub Releasesvjoy(Windows) - virtual joystick driverevdev(Linux) - virtual input device
TypeScript:
react+react-dom- UI frameworkreact-konva/konva- canvas editorzustand+immer- state management with undo/redoreact-colorful- color pickerreact-icons- icon packreactjs-popup- modals and menusqrcode- QR code generation for mobile connection@tauri-apps/plugin-updater- update check + install from frontend
OR