We just shipped v3.8.0 of OpenROM — a free, open-source
retro gaming toolkit built with Flutter + Dart.
From day one, OpenROM was designed to be 100% offline.
No telemetry, no accounts, no network requests. But users
kept asking for two things: auto-update notifications and
RetroAchievements hash verification.
The challenge: how do you add online features to an
offline-first app without betraying its core philosophy?
The approach
Every online feature is:
- Disabled by default (false in SharedPreferences)
- Requires explicit user opt-in in Settings
- Fails silently — never blocks offline functionality
- Clearly documented in SECURITY.md
abstract class OnlinePrefs {
static const String autoUpdateEnabled =
'online_auto_update_enabled'; // default: false
static const String raEnabled =
'online_ra_enabled'; // default: false
}
Auto-update check
Simple GitHub releases API call on startup (if enabled):
static Future<UpdateCheckResult> checkForUpdate(
String currentVersion) async {
try {
final response = await http.get(
Uri.parse(_repoApi),
headers: {'Accept': 'application/vnd.github+json'},
).timeout(Duration(seconds: 10));
// compare semver, return result
} catch (e) {
return UpdateCheckResult(error: e.toString()); // fail silently
}
}
No auto-install. Just a banner. User clicks download
themselves.
RetroAchievements hash lookup
MD5 the ROM file, hit the RA API, show a badge on the
ROM card:
Future<RaHashResult> lookupHash(String filePath) async {
final hash = await computeMd5(filePath);
// hit retroachievements.org/API/API_GetGameInfoByMD5.php
// return result — never throws
}
This solves a real pain point: downloading a 4GB PS2 ISO
only to discover achievements are USA-only. Now OpenROM
tells you before you convert.
Stack
- Flutter + Dart — cross-platform GUI + core logic
-
Dart monorepo —
core/package +gui/app - No Python, no Nuitka — pure Dart = zero AV false positives
- GPL v3
Links
GitHub: https://github.com/M5Devs/OpenROM
Latest release: v3.8.0
What's your approach to adding online features to
offline-first apps? Happy to discuss in the comments.
Top comments (0)