HTML5 Game to EXE: Turn Your Browser Game Into a Desktop App
How to ship a Three.js, Phaser, or plain-canvas browser game as a real desktop app. What happens to WebGL performance in a wrapper, the three Chromium settings that matter for games, Steam and itch.io distribution, and signed installers without touching Electron.

Browser games are quietly becoming desktop games. Vampire Survivors started life as an HTML5 game in a wrapper. A huge slice of the io-game and idle-game catalog on Steam and itch.io is Chromium with the address bar removed. If you've built something in Three.js, Phaser, PixiJS, or plain canvas, the distance between "playable at my URL" and "installable game with an icon in the dock" is much shorter than it looks — and players treat the two very differently. A download is a commitment; a tab is a whim.
Here's what actually changes when your game leaves the browser, the settings that matter, and the honest tradeoffs.
Will it perform? (The first question everyone asks)
A wrapped game runs on the same Chromium, the same V8, and the same ANGLE graphics layer your players already use in Chrome. WebGL and WebGPU performance is effectively identical — the wrapper is not an emulator, it is the browser, minus the browser.
In practice, wrapped games often run better than their in-browser selves:
- No tab competition. Your game isn't sharing the GPU process with someone's 40 open tabs and three extensions.
- One known browser version. You pick the Chromium your game ships with. "Works in Chrome, stutters in Safari, breaks on iOS WebGL" stops being your problem — every player runs the exact engine you tested.
- No extension interference. Ad blockers and userscripts can't reach into your render loop.
The GPU requirements don't change: if your Three.js scene runs at 60fps in Chrome on a given machine, it will in the wrapper too.
The three settings that make or break a wrapped game
These are the differences between "we put a game in Electron" and "this feels like a native game." If you build a wrapper yourself, get these right; if you use a platform, check that it does.
1. Background throttling off. Browsers throttle requestAnimationFrame and timers hard when a window loses focus — fine for a dashboard, fatal for a game. Your physics stalls, your WebSocket-based multiplayer desyncs, and idle games stop idling. The wrapper needs backgroundThrottling: false on the game window so your loop keeps its cadence when the player alt-tabs.
2. Audio without the gesture dance. Browser autoplay policy means every web game starts with a "click to enable sound" screen. A desktop app can set its autoplay policy so your title music starts when the game does — one small thing that instantly reads as "real game" instead of "website."
3. True fullscreen and pointer lock, no permission bars. In the browser, fullscreen shows the "press Esc to exit" banner and pointer lock needs a user gesture per session. In a wrapper both are just… on, when you want them. First-person cameras and drag-to-orbit controls in Three.js feel native because they are.
Also free, no configuration required: the Gamepad API works, high-DPI rendering works, and there's no address bar reminding everyone this used to be a website.
Saves that actually survive
Browser storage is a lease, not a deed: under storage pressure, browsers evict IndexedDB and localStorage for origins the user hasn't visited recently — which for a game means deleted save files. In a desktop app, that storage lives in the app's own profile on disk. Nobody's disk-space cleanup silently wipes a hundred hours of progress. If your save system is localStorage-based today, it gets durable for free the moment you wrap.
Hosted or bundled? (Choose your update model)
There are two ways to put a web game in a desktop shell:
- Bundle the build into the binary. Fully offline, but every balance patch is a re-release: rebuild, re-sign, re-notarize, redistribute.
- Point the wrapper at your hosted URL. The app is a thin, signed shell; the game is whatever your server serves. Deploy your Vite build and every installed copy has the patch on next launch — no re-release, ever.
The hosted model is what Deskifier ships. For a live game where you tune drop rates weekly, updating by deploying is the entire pitch.
The part nobody warns you about: shipping
Making the wrapper is a weekend. Shipping it is the project: Windows installers flagged by SmartScreen until you buy code signing, macOS Gatekeeper refusing unsigned builds outright, notarization queues, auto-update infrastructure, and doing all of it three times for Mac, Windows, and Linux. Our Electron comparison covers the DIY route honestly — it's real engineering, and it's permanent maintenance.
The alternative: point Deskifier at your game's URL and get signed, notarized installers for all three platforms with auto-update built in. Dev builds are free, so you can playtest the desktop feel today. If you develop locally, the CLI wraps your dev server too:
npm install -g @deskifier/cli
deskifier dev --url http://localhost:5173
Your Three.js game, in its own window, tray icon and all, before your coffee's done.
What about Steam and itch.io?
The reason most people search "HTML5 game to exe" in the first place. The honest breakdown:
- itch.io takes a plain Windows build or a zipped app directly — any properly-built wrapper qualifies. Upload, done.
- Steam happily distributes Electron-family games (a meaningful chunk of its catalog is exactly that), and Steam's own installer pipeline means you don't even need code signing for Steam-only distribution. What Steam doesn't give you for free is Steamworks integration — achievements, the overlay, cloud saves, workshop. Those need the Steamworks SDK wired in as a native module, which is its own engineering project regardless of which wrapper you use.
- Mac App Store and Microsoft Store are where a wrapper platform earns its keep: entitlements, sandboxing, provisioning, and review-ready packaging are handled for you.
If your plan is "sell the game on itch, maybe Steam later, no achievements at launch" — a wrapped build gets you there without writing a line of native code.
The 10-minute version
- Host your game build anywhere (it's probably already up).
- Create an app, paste the URL, pick fullscreen as your window default.
- Build the free dev version, install it, feel the difference alt-tab makes.
- When it feels right: production builds, signed and store-ready.
The web made your game easy to build. A desktop wrapper makes it feel like something people bought.