I build RKMovies, a small media player that started life as a PWA. The Android APK is 1.17 MB. People keep asking why there is also a Windows installer, and why it sits at 29.5 MB when the web app is way smaller. This is the build diary.
the PWA does the heavy lifting
The whole player is HTML/CSS/JS served from the project page. It installs as a PWA, works offline after the first load, and updates itself by swapping the service worker. On Android I wrap the same bundle in a webview and ship the 1.17 MB Android APK.
why an exe at all
A lot of users (mostly family TV setups on old PCs) want a desktop icon and a double-click. They do not want to open a browser and install a PWA from a menu. So the desktop build is the same web bundle plus a WebView2 bootstrapper.
what actually costs the 29.5 MB
- the WebView2 runtime bootstrapper, which is most of the size
- a pre-cached app shell so the first launch works fully offline
- the player code itself, which is under 2 MB
I could ship an evergreen WebView2 reference and cut the installer down hard, but on the old machines this app targets the runtime is usually missing, and a separate runtime download scares people off. Self-contained wins on support tickets even though it costs megabytes.
the boring parts that matter
- a single-instance lock, so double-clicking the icon never spawns five windows
- the exe registers a custom URL handler and forwards the link to the already-running instance
- updates reuse the same multi-endpoint config check the PWA uses, then swap files only while no window is open
- zero telemetry; the only network calls are the ones the user triggers
On Windows, grab the 29.5 MB Windows installer. On Android, the APK above. Same player either way: hardware decode, gesture HUD, multi-audio tracks, WebVTT subtitles, under 15 MB RAM at runtime.
Disclosure: I am the developer of RKMovies. Ask me anything about the packaging.
Top comments (5)
The interesting part here is that packaging size is a product trade-off, not merely a build artifact. Users experience the first install, first launch, offline behavior, and update reliability as one system. Reporting those milestones alongside the binary size makes it easier to decide whether a bootstrapper, bundled runtime, or alternate distribution is the right compromise.
good point, noted for the next build.
The evergreen vs self-contained decision is the right call for your audience — a missing runtime on a family TV PC is a support ticket you'd be answering forever.
One question: does the single-instance lock hold up when the exe is launched from the URL handler while the app is minimized to tray? I've seen a few wrappers where the second launch wins and the first window gets orphaned.
appreciate the read! size budget is the first thing i check every release too — apkanalyzer compare view catches the sneaky dependency bumps before they ship.
The compare view is genuinely underrated — it catches the "one small library added 300KB" case that nobody notices in a code review. On the Windows side, do you measure the installer the same way, or is it mostly a manual "did it jump?" check?