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')
})
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"
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)