NeoStation provides a fast, lightweight, and customizable experience for managing and launching retro games across desktop and mobile devices, with seamless integration for RetroArch and standalone emulators.
Features
- Modern & customizable UI: Designed for both large screens and handheld devices, with themes and animations.
- Collection management: Intuitively organize your ROMs and platforms.
- Multi-disc ROM organization: Automatically create
.m3u playlists for your multi-disc games and organize them into game folders.
- RetroArch & standalone emulator integration: Easy configuration and auto-detection.
- Multi-platform support: Windows, Linux, macOS, and Android.
- Lightweight & fast: Built with web and native technologies for maximum performance.
- Advanced configuration: Deep customization options for power users.
- Cloud save sync (NeoSync): Register, log in, email verification, and profile management.
- RetroAchievements support: Track achievements and leaderboard progress.
- ScreenScraper integration: Automatic metadata and media scraping.
- Gamepad & keyboard navigation: Full controller support across all platforms.
- 12 languages supported: English, Spanish, Portuguese, Russian, Chinese (Simplified & Traditional), French, German, Italian, Indonesian, Japanese, Korean.
Multi-disc ROM Organization
The built-in organizer helps prepare multi-disc games for emulators that use .m3u playlists:
- Open Settings > Tools.
- Select Organize Multi-Disc Games.
- NeoStation recursively scans all configured ROM folders and detects disc sets using
Disc, Disk, or CD filename markers.
- Each detected set is placed in a game folder with an
.m3u playlist. Existing playlists are reused rather than duplicated.
Folders that already contain .m3u playlists are skipped during the scan.
| Platform |
Status |
Notes |
| Windows |
✅ Supported |
x64 |
| Linux |
✅ Supported |
x64, ARM64 (AppImage, Flatpak) |
| macOS |
✅ Supported |
Apple Silicon & Intel |
| Android |
✅ Supported |
ARM64, Android TV compatible |
Prerequisites
- Flutter SDK ≥ 3.9.2 — but CI pins an exact version in
.fvmrc, and
pubspec.lock is committed as that version resolves it. Build on the pinned
version (fvm use reads .fvmrc directly) or CI will reject your lockfile:
every job runs flutter pub get --enforce-lockfile.
- Dart SDK (bundled with Flutter)
- Git
- RetroArch or standalone emulators
Installation
Linux (Flatpak)
# Coming soon to Flathub! In the meantime, you can build locally:
flatpak-builder --user --install-deps-from=flathub \
--repo=repo --force-clean \
build-dir linux/flatpak/com.neogamelab.neostation.yml
Steam Deck
Download the x86_64 AppImage, then add it to Steam and launch it from there —
either from Game Mode, or from the desktop with Steam running:
- Steam → Games → Add a Non-Steam Game to My Library → Browse
- Set the file filter to All Files (the picker hides
.AppImage by default)
- Select the AppImage, then launch NeoStation from your library
This matters for the controls. With Steam not running, the Deck’s controller sits
in lizard mode, where the hardware emulates a keyboard and mouse instead of a
gamepad: the D-pad sends arrow keys, A/B send Enter/Escape, the trackpad moves the
mouse pointer, and the bumpers send nothing at all. Running through Steam hands
the app a proper virtual gamepad, and every button works.
So if the shoulder buttons seem dead, or A/B behave oddly, or a mouse cursor sits on
screen, the app isn’t at fault — it’s being run outside Steam.
Build from source
# Clone the repository
git clone https://github.com/misobadev/neostation-frontend.git
cd neostation-frontend
# Install dependencies
flutter pub get
Build-time Configuration
NeoStation uses compile-time environment variables (--dart-define) for Flutter configuration, and Gradle properties for Android signing. No .env files are required at runtime.
Flutter variables (via --dart-define or .env)
Create a .env file from .env.example for local development.
| Variable |
Description |
SCREENSCRAPER_DEV_ID |
ScreenScraper developer ID |
SCREENSCRAPER_DEV_PASSWORD |
ScreenScraper developer password |
RetroAchievements no longer uses a build-time key. Each user signs in with their own RetroAchievements username and web API key (from retroachievements.org/controlpanel.php) inside the app.
Signed-in users automatically refresh the RetroAchievements game/hash catalogue
for consoles in their library once per day. This runs in the background even
with startup matching disabled; only existing ROM hashes are looked up in that
case. Settings → Tools → Match RetroAchievements Games forces a catalogue
refresh before matching and hashing. Downloads use the user’s own API key;
failed downloads retain the saved catalogue, and manual matches are preserved.
Android release signing (optional)
If you want your release APKs signed with a release certificate (required for app store distribution and seamless user upgrades), create android/key.properties from android/key.properties.example.
storePassword=your_password
keyPassword=your_password
keyAlias=upload
storeFile=../release.jks
If android/key.properties is not present, the build automatically falls back to debug signing, which is sufficient for local testing and sideloading.
GitHub Actions CI/CD
The release workflow (.github/workflows/build-and-deploy.yml) reads build secrets from your repository. You can store them as Environment secrets.
Required for all platforms:
| Secret / Variable |
Description |
SCREENSCRAPER_DEV_ID |
ScreenScraper developer ID |
SCREENSCRAPER_DEV_PASSWORD |
ScreenScraper developer password |
Required for Android release signing:
| Secret |
Description |
ANDROID_KEYSTORE_BASE64 |
Your release.jks file encoded as base64 (binary, not text). See below. |
ANDROID_KEYSTORE_PASSWORD |
Keystore password |
ANDROID_KEY_PASSWORD |
Key password |
ANDROID_KEY_ALIAS |
Key alias (e.g. upload) |
Important: ANDROID_KEYSTORE_BASE64 must be the binary keystore file (.jks), not the key.properties text file. To encode it:
# Linux / macOS
base64 -w 0 release.jks
# Windows PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("release.jks"))
If the Android secrets are missing, the CI build falls back to debug signing (users will need to uninstall before installing a new release).
Running
# Development
flutter run \
--dart-define=SCREENSCRAPER_DEV_ID=your_id \
--dart-define=SCREENSCRAPER_DEV_PASSWORD=your_password
# Production builds
# Replace these with your actual keys
DART_DEFINES="--dart-define=SCREENSCRAPER_DEV_ID=your_id --dart-define=SCREENSCRAPER_DEV_PASSWORD=your_password"
# Android APK
flutter build apk --release $DART_DEFINES
# Windows
flutter build windows --release $DART_DEFINES
# Linux
flutter build linux --release $DART_DEFINES
# macOS
flutter build macos --release $DART_DEFINES
Project Structure
lib/
├── data/
│ └── datasources/ # SQLite access, migrations, raw queries
├── l10n/ # Localization files (12 languages)
├── models/ # Data models
├── providers/ # ChangeNotifier state management
├── repositories/ # Data access abstraction layer
├── screens/ # Application pages
├── services/ # Business logic and external APIs
├── sync/ # Provider-agnostic cloud sync (SyncManager + adapters)
├── themes/ # App themes
├── utils/ # Helpers and utilities
├── widgets/ # Reusable UI components
├── main.dart # Entry point
For more details, see ARCHITECTURE.md.
Local Packages
Third-Party Licenses & Credits
NeoStation is built upon the incredible work of the open-source community. To achieve the specific performance and compatibility goals of this project, we utilize modified versions of several libraries.
These packages are “vendored” within the /packages directory to ensure long-term stability and to include custom optimizations:
| Package |
Description |
gamepads |
Cross-platform gamepad input (based on Flame Engine’s gamepads) |
flutter_7zip |
FFI bindings for 7-Zip archive extraction |
Systems & Emulator Definitions
NeoStation’s system configurations, emulator definitions, and launch arguments are maintained in this repository under assets/systems/.
If you want to add new emulators, fix launch arguments, or update system configurations, please open a pull request here.
The bundled assets/manifest.json drives the over-the-air systems update mechanism, so compatible changes can be delivered to existing installs without requiring a full app release.
Contributing
Please read CONTRIBUTING.md for guidelines on bug reports, feature requests, and pull requests.
Security
If you discover a security vulnerability, please follow the instructions in SECURITY.md to report it responsibly.
Project Team
Lead
Official Co-Maintainers
These co-maintainers and collaborators work very hard to make NeoStation what it is today.
License
This project is licensed under the GNU General Public License v3.0 (GPL-3.0). See LICENSE.md for details.
Third-party components and assets have their own licenses — see NOTICE.
评论