MobiFlight is a hybrid app:
- C# backend handles flight sim integration, hardware communication, and the execution engine
- Frontend provides the configuration UI. The frontend is a React + TypeScript app using Vite, Tailwind, and shadcn/ui. It runs inside a WebView2 control embedded in the C# backend window.
- Frontend and backend communicate through a JSON message bridge — the React side calls
PostMessageand C# handles it via handlers inBrowserMessages.
The main backend subsystems are:
- Execution engine - reads variables from the flight simulator on a polling timer and applies user-defined mappings to drive output devices
- Flight sim connectors - separate integrations for MSFS (SimConnect), FSX/P3D (FSUIPC), and X-Plane
- Hardware device drivers - Arduino-based MobiFlight boards, Arcaze USB, MIDI boards, USB HID game controllers, and others
- Browser message layer - the IPC bridge between C# and the React UI
In development you run two things side by side:
- The frontend dev server works conveniently in Visual Studio Code, in the provided dev container
- The C# backend in Visual Studio. When you start the backend with the Debug build target it connects to the frontend dev server at
localhost:5173and loads it automatically.
The easiest way to get started is with the included dev container — dependencies and Playwright browsers for unit tests are installed automatically on first startup.
- Follow the instructions to install Docker and the Dev Containers extension in Visual Studio Code.
- Select Open Folder.. in VS Code, navigate to
src/MobiFlightConnector/frontend/ - When prompted by VSCode, select Reopen in Container
The first time takes a few minutes to configure while the necessary images are downloaded and dependencies install. After the container opens VSCode may warning about an auto-configured task to run. Accept the task, and the frontend will start.
The frontend is served at http://localhost:5173.
To manually start the frontend, use the command palette (CTRL+SHIFT+P) to select the Tasks: Run Task command, then run Start frontend.
The backend is a C# desktop application. and it must be running for full functionality. Once your devcontainer has finished starting up, and you see the localhost url in the devcontainer terminal output, proceed into Visual Studio.
Open MobiFlightConnector.sln and use the Debug build target to Run the project — this connects to the frontend dev server at localhost:5173.
Translation files are in public/locales/{lang}/translation.json. The app uses react-i18next — all user-facing strings must go through t(). Core languages that must be complete before a PR can be merged: en, de, es.
npm run check:i18n # run both checks below
npm run check:translations # missing keys per language
npm run check:translations -- fi # missing keys for a specific language
npm run check:hardcoded-strings # components with hardcoded strings
npm run check:hardcoded-strings:verboseAdding a new locale folder under public/locales/{lang}/ is enough for the React UI itself — i18next discovers and loads it automatically. However, language switching still happens in the legacy WinForms Settings dialog, not in the React UI. To make a new language selectable, add it to InitializeLanguageComboBox() in src/MobiFlightConnector/UI/Panels/Settings/GeneralPanel.cs (outside frontend/).
See tests/README.md.
The old WinForms dialogs are legacy. All new UI work goes into the React frontend; the goal is to migrate everything over time. If you are adding a feature that touches the UI, build it in the frontend rather than WinForms. If unsure, discuss your ideas first on Discord #development channel.
