A desktop app that turns setting up a RetroFE-based emulation system from a weekend of hand-editing config files into a guided, repeatable process. Point it at your ROMs, curate your library, and generate a complete, validated RetroFE installation for Mac or PC.
The Problem
RetroFE appeals to a certain kind of person: the one who wants to know exactly what their system is doing and why. Unlike LaunchBox — which is polished, capable, and Windows-only — RetroFE is transparent. Every collection, every launcher, every theme is an explicit config file. Nothing is hidden. For building a dedicated arcade machine or a clean multi-system setup, that philosophy is exactly right.
The problem is that "explicit" means "manual." Adding a single console to RetroFE means touching at least five separate files: a global settings file, a per-collection config, a launcher definition with the correct emulator command-line syntax, a menu list, and the right artwork folders in the right places. Do it wrong in any one of them and the system either silently ignores the collection or throws a cryptic error. There is no wizard, no validation, and no auto-detection of anything.
It gets harder across platforms. A RetroFE setup built on Windows uses Windows paths and conventions. Bringing it to a Mac — where there is no pre-built binary, let alone an ecosystem — means starting over from scratch. I wanted to maintain one setup and deploy it to both machines.
What RetroStack Does
RetroStack manages the full pipeline from raw ROM files to a deployable RetroFE installation:
- ROM scanning and matching — scan folders across multiple sources, hash each file, and match against No-Intro and Redump reference databases to establish canonical game identities
- Library curation — browse matched games, organise them into collections, tag favourites, and manage per-game overrides
- Asset resolution — discover artwork, videos, and screenshots from asset vaults and match them to games using fuzzy matching and confidence scoring, with manual pinning for edge cases
- Emulator configuration — define launch profiles per system and per game, with platform-specific paths resolved automatically for Mac or Windows
- Build generation — produce a complete, validated RetroFE installation via a six-stage pipeline with real-time progress reporting
- Delta deployment — only changed files transfer on subsequent builds, keeping updates fast
The Interesting Parts
Knowing which game a ROM actually is
ROM files are notoriously inconsistently named. "Super Mario World (USA).sfc", "Super_Mario_World.sfc", and "SMW.sfc" are all the same game. String matching on filenames is unreliable and fragile.
RetroStack hashes every ROM using three algorithms in sequence — CRC32 for a fast initial pass, then MD5, then SHA1 — and looks up the result against No-Intro and Redump reference databases. CRC32 is cheap and eliminates most non-matches immediately; SHA1 is authoritative for disc images where CRC32 collisions are a concern. The fallback hierarchy means you get the right answer without running the expensive hash on every file unnecessarily.
Once matched, each game has a canonical identity that persists regardless of what the file is called or where it moves.
Connecting ROMs to artwork
Game artwork arrives in asset packs with their own naming conventions, none of which necessarily match the ROM filenames or the canonical game names in the reference database. A folder of SNES box art might have files named "Super Mario World (USA) [!].png", "SuperMarioWorld.png", or just "super mario world.png".
The asset resolver works through a ranked pipeline: exact filename match first, then fuzzy matching at above 85% similarity using string distance scoring, then manual user pins as the final override layer. Each candidate gets a confidence score, and the best match is stored in the database so future builds reuse the decision without re-matching. Users can review low-confidence matches and pin specific assets to specific games; that pin survives rebuilds.
One config, two platforms
Emulator configurations are defined in TOML files with separate sections for macOS and Windows. Launch commands, executable paths, and platform-specific flags are all declared in the same file and resolved at build time for the target platform.
[platforms.macos]
executable = "Dolphin.app/Contents/MacOS/Dolphin"
launch_command = "{exe} -e {rom}"
[platforms.windows]
executable = "Dolphin.exe"
launch_command = "{exe} /e {rom}"
A configuration authored on Mac generates a Windows-correct build and vice versa. The path conventions, executable names, and command-line syntax are handled by the build system rather than by the person maintaining the setup.
Collections without duplication
A RetroFE setup often wants multiple views of the same games — a full system list, a top 100, a genre collection, a kid-friendly set. Duplicating ROMs and artwork for each view isn't feasible at scale.
RetroStack uses a master/compound pattern: master collections hold the canonical ROM list and media references; visible collections are compound views that select subsets via filter rules and reference the master's assets via symlinks. A game's artwork lives in one place regardless of how many collections reference it.
A build you can trust
The six-stage build pipeline — Resolve, Provision, Materialize, Configure, Generate, Finalize — runs pre-flight validation at each stage and reports problems before they produce a broken output. Missing bezels, unresolved emulator paths, theme validation failures, and misconfigured collections all surface as warnings or errors in the build log rather than as silent failures at runtime. Progress is reported in real time via event streams to the UI, with per-system status visible as the build runs.
Built With
- Tauri v2 — Rust backend, SolidJS frontend, ~5MB binary vs Electron's 120MB
- SolidJS — fine-grained reactivity for browsing libraries of 1,000+ games without performance degradation
- Rust — ROM hashing, build pipeline, filesystem operations, SQLite via rusqlite
- SQLite — library state, asset pins, build profiles, game metadata; survives rebuilds
- TanStack Query — data fetching and cache management for the SolidJS frontend
Status
Active development. ROM scanning, asset resolution, emulator configuration, and build generation are working. Cross-platform deployment (Mac and Windows from a single database) is the current focus.