HTML Game to Desktop App: Turn Your Browser Game Into an EXE
How to turn an HTML, JavaScript or WebGL game into a desktop app for Windows, macOS and Linux. What changes outside the browser, bundled vs hosted builds, saves, signing, and shipping to Steam and itch.io without touching Electron.

Browser games are quietly becoming desktop games. Vampire Survivors started life as an HTML5 game in a wrapper. A big slice of the idle and roguelite catalog on Steam and itch.io is Chromium with the address bar removed. If you've built something in Phaser, Three.js, PixiJS, Construct, GDevelop or plain canvas, the distance between "playable in a tab" and "a game with an icon on the desktop" is shorter than it looks, and players treat the two very differently. A download is a commitment; a tab is a whim.
This guide covers what changes when an HTML game becomes a desktop app, the decisions you have to make, and the fastest way through them. If you want the full list of tools first, see every way to turn an HTML game into a desktop app, compared.
What "HTML game to desktop app" actually means
Every route works the same way underneath: your game's index.html and assets run inside a browser engine that has no tabs, no address bar and no extensions, packaged as a normal program. On Windows that's an .exe installer, on macOS a .app inside a .dmg, on Linux a .deb or AppImage.
The tools differ in which browser engine they ship and how much of the rest they handle:
- Bundled Chromium (Electron, NW.js, Deskifier): every player runs the exact engine you tested. Bigger download, identical behaviour everywhere.
- The system's web view (Tauri, Neutralino, most small "HTML to EXE" tools): a tiny download, but your game runs in Edge WebView2 on Windows, Safari's WebKit on macOS and WebKitGTK on Linux. That's three engines with three sets of WebGL quirks.
For games, bundled Chromium is usually the right call. We go into why in Electron vs Tauri vs NW.js for games.
Will it perform?
A Chromium wrapper runs the same V8 and the same graphics layer your players use in Chrome, so WebGL and WebGPU performance is effectively the same. The wrapper isn't an emulator; it is the browser, minus the browser.
In practice wrapped games often run better than in a tab:
- No tab competition. Your game isn't sharing a GPU process with forty open tabs and three extensions.
- One known engine version. "Works in Chrome, stutters in Safari" stops being your problem.
- No extensions in your render loop. Ad blockers and userscripts can't reach in.
If your scene runs at 60fps in Chrome on a machine, it runs at 60fps in the desktop build.
The settings that make it feel like a game, not a website
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 when a window loses focus. Fine for a dashboard, fatal for a game: physics stalls, multiplayer desyncs, idle games stop idling. In Electron that's backgroundThrottling: false on the game window.
2. Audio without the click-to-start screen. Browser autoplay rules are why every web game opens with "click to enable sound". Electron's default autoplay policy doesn't need a gesture, so your title music can start with the game.
3. Real fullscreen, real window options. No "press Esc to exit fullscreen" banner and no browser shortcuts fighting your controls. Players expect windowed, borderless and fullscreen modes, and a way to pick the monitor.
4. A settings menu. Desktop players expect to change window mode, resolution and volume without finding them in your game's UI. Most wrappers leave that for you to build.
The Gamepad API and high-DPI rendering work as they do in Chrome, with no extra setup.
Saves that survive
Browser storage is a lease, not a deed. Under storage pressure browsers evict IndexedDB and localStorage, and players wipe it themselves when they clear site data. For a game that means deleted save files.
In a desktop app that storage lives in the app's own profile on disk, which is much safer, but it's still hidden and still gone if the player uninstalls. Deskifier game builds go a step further: they copy browser storage to a visible GameSaves folder every few minutes and on quit, restore it automatically after a reinstall, and let players export and import their saves. If your save system uses localStorage today, none of this needs code. (If you ship on Steam, point Auto-Cloud at that folder and saves follow the player between machines.)
Bundled or hosted?
There are two ways to put a web game in a desktop shell:
- Bundle the build into the app. Your game files ship inside the installer and load from the player's disk: fast launches, fully offline, and nothing for your server to do. This is the right default for most games, and the only option for a game you sell on Steam or itch.io.
- Point the app at a hosted URL. The app is a thin, signed shell around whatever your server serves. Deploy and every installed copy has the patch on next launch. Good for live, online-only games that you tune weekly.
Deskifier does both. Upload the folder your engine exports (the one with index.html, or a .zip of it) and it's bundled; paste a URL instead and it's hosted.
The part nobody warns you about: shipping
Making the wrapper is a weekend. Shipping it is the project:
- Windows shows a SmartScreen warning on unsigned installers until you buy code signing.
- macOS won't open an unsigned, un-notarised app without a trip to System Settings, and building and signing a Mac app traditionally needs a Mac.
- Updates for copies you sell from your own site need update infrastructure.
- Stores each have their own upload tool: SteamPipe and
.vdfscripts, itch.io's butler, Epic's BuildPatchTool.
Multiply that by three operating systems. Our Electron comparison covers the do-it-yourself route honestly: it's real engineering, and it's maintenance forever.
The 10-minute version with Deskifier
- Create a game app and upload your HTML5 build folder (or a
.zip, or a URL). - Pick the window mode, icon and settings-menu options in the dashboard. Turn on Steam or Discord if you use them.
- Build the free dev version for Windows, macOS and Linux, install it, and play it. No Mac needed for the Mac build.
- When it's ready for players, build signed installers or push straight to itch.io, Steam or Epic from the Builds page.
Your game code doesn't change. The extras are there when you want them: window.deskifier.steam for achievements and stats, window.deskifier.discord for Rich Presence, window.deskifier.game for the settings menu and saves.
What about Steam and itch.io?
It's the reason most people search "HTML game to EXE" in the first place.
- itch.io accepts any properly built Windows, macOS or Linux download. Set your project to Downloadable and upload one build per platform.
- Steam reviews the game, not the engine; plenty of its catalog is Chromium underneath. What you need is a native build per platform, uploaded to your depots, and Steamworks wired in if you want achievements, stats, cloud saves or the overlay. We cover that end to end in how to put an HTML5 game on Steam.
- Mac App Store and Microsoft Store add sandboxing, entitlements and review-ready packaging, which a platform handles for you.
The web made your game easy to build. A desktop app makes it feel like something people own. Try a free dev build, or read more on turning a browser game into a desktop game.