DEV Community

Indexflow
Indexflow

Posted on

Website to EXE: 4 Ways to Ship a Web App as a Windows Desktop App (2026)

Every few months someone on my team asks the same question: "Can we give the client a desktop app instead of a URL?"

Usually the web app already exists and works fine. The customer just wants an icon on the desktop, a window without a browser address bar, and something they can install on 40 machines in an office that treats "open Chrome and go to this URL" as an unsolvable IT problem.

There are four realistic ways to do this in 2026. I've shipped with all of them. Here's the honest comparison - including the parts people leave out of the tutorials.

1. Electron

The default answer, and still the most capable one.

Electron bundles Chromium and Node.js with your app. You get a real Node process, filesystem access, native menus, auto-update via electron-updater, and a mature ecosystem where every problem you hit has a Stack Overflow answer from 2019.

const { app, BrowserWindow } = require('electron')

app.whenReady().then(() => {
  const win = new BrowserWindow({ width: 1200, height: 800 })
  win.loadURL('https://your-web-app.example.com')
})
Enter fullscreen mode Exit fullscreen mode

That's a working desktop app in eight lines. The cost shows up later:

  • Installer size: 80-150 MB even for a wrapper, because Chromium ships with you.
  • Memory: each app is its own browser. Three Electron apps open is three Chromiums.
  • Maintenance: you now own a Node project - dependency updates, a build pipeline per platform, and a code-signing story.

Electron is right when you need real native capability: local file processing, hardware access, a background service, offline-first storage. It's overkill when all you needed was a window.

2. Tauri

Tauri uses the operating system's own webview (WebView2 on Windows) instead of bundling Chromium, with a Rust backend.

The size difference is not subtle. A comparable wrapper lands around 3-10 MB instead of 120 MB. Memory usage is meaningfully lower because you're sharing the system webview.

The trade-offs:

  • Rust in your build chain. You don't have to write much of it, but you do have to install it, understand build errors, and keep the toolchain current.
  • Rendering differences. WebView2 on Windows, WebKit on macOS, WebKitGTK on Linux. Your CSS is now tested against three engines, not one. That single-engine guarantee is a real part of what Electron sells.
  • Ecosystem depth. Much better than it was, still smaller than Electron's.

Tauri is the right call for a team that is comfortable with a Rust toolchain and cares about install size - which, for a distributed desktop tool, users genuinely notice.

3. Nativefier

Nativefier is a command-line tool that generates an Electron app from a URL:

npx nativefier "https://your-web-app.example.com" --name "My App"
Enter fullscreen mode Exit fullscreen mode

It's the fastest path to something that runs on your own machine, and it's excellent for personal use - turning a web tool you keep open all day into its own window with its own alt-tab entry.

For shipping to customers it thins out quickly. You still inherit the Electron footprint, you get the default Electron packaging story, and the polish work - proper installer, signed binary, auto-update, branded splash - is all still ahead of you. It's a wrapper generator, not a distribution pipeline.

4. No-code converters

The fourth option is to hand a URL to a service that returns a signed installer. WebsiteToApp is the one I use for this (disclosure: I work on it), and the category also includes several Android-first tools that added desktop output later.

The pitch is narrow and worth being precise about: you paste a URL, choose an icon, splash screen and window behaviour, and get back a Windows .exe installer - plus Android APK/AAB from the same configuration if you need both. No build chain on your machine, no signing setup, no CI.

What you're actually buying is the packaging pipeline, not the wrapper. The wrapper is the easy part. Installers, icons at every required size, versioning so an update installs over the old app instead of beside it, and keeping up with OS requirements - that's the part that eats a week.

What you're giving up is equally clear: you don't own the build, you can't drop into native code, and you're constrained to what the configuration exposes. If your app needs to read a local serial port or spawn a background daemon, none of this applies to you - go back to option 1 or 2.

The matrix

Electron Tauri Nativefier No-code converter
Setup time Hours-days Hours-days Minutes Minutes
Installer size 80-150 MB 3-10 MB 80-150 MB 60-90 MB
Native code access Full (Node) Full (Rust) Limited None
Rendering engine Bundled Chromium System webview Bundled Chromium Bundled
Installer + signing You build it You build it You build it Included
Ongoing maintenance Yours Yours Yours Vendor's
Best for Native-capability apps Size-sensitive apps Personal tools Shipping an existing web app

How to actually choose

Ask one question first: does the app need to do something a browser tab can't?

If yes - local files, hardware, background work, deep OS integration - you need a real framework. Pick Electron for ecosystem and a guaranteed rendering engine, Tauri if install size matters more and Rust doesn't scare your team.

If no, and this is fundamentally "the same web app, in a window, that a non-technical person can install" - then the framework isn't the product. The packaging is. Nativefier if it's just for you; a converter if you're handing it to customers and don't want to own an installer pipeline forever.

The failure mode I see most often is a team spending three weeks building an Electron distribution setup for an app whose entire requirement was "an icon on the desktop." The framework was never the hard part. The .exe that installs cleanly on someone else's Windows machine is.


Working on the Android side too? Converting a website to an Android app has a different set of gotchas - mostly Google Play's, not yours.

Top comments (0)