Back to all posts

React on the Desktop: When a Window Beats a Tab

Jun 28, 2026
11 min read
React on the Desktop: When a Window Beats a Tab

There's a specific moment where the desktop pitch becomes irresistible. You've built a genuinely good React app, it lives in a browser tab, and someone asks "can we make it a real app?" — with a dock icon, a name, a window of its own. And the answer is yes, easily, with the same React code you already have. Electron and Tauri will both wrap it into a program that installs like any native app. The demo takes an afternoon and feels like magic.

So the tempting question is "how do I turn my React app into a desktop app," and it's the wrong one to lead with. The right question — the one that actually determines whether this is worth doing and which tool to reach for — is what do I gain by leaving the browser at all? Because a desktop wrapper that just shows your website in a frameless window is a worse browser tab: heavier, harder to update, and offering the user nothing they didn't already have. The whole justification for going desktop is the stuff a browser tab structurally cannot do, and if you don't need that stuff, you probably shouldn't be here.

This article is about that line — what the desktop actually buys you — and the honest tradeoff between the two tools that get you there.

What a Browser Tab Genuinely Can't Do

Start with the reason to leave the browser, because it's the whole point. A web page runs in a sandbox, deliberately walled off from the machine it's on — that's a security feature, not a limitation to complain about. But it means there are real capabilities a tab simply doesn't have, and those capabilities are your entire reason for going desktop.

Deep filesystem access — reading and writing arbitrary files on the user's disk, not the sandboxed trickle a browser allows. Real OS integration — a tray icon, native menus, global keyboard shortcuts that work when your app isn't focused, notifications that feel like the system's own. Talking to native or system-level resources the browser keeps off-limits. Working genuinely offline as a first-class program, not a web page hoping its service worker cached the right things. If your app needs one of these, the desktop isn't a nicety — it's the only place the feature can exist.

And the contrapositive matters just as much: if your app needs none of these — if it's fundamentally a web app that someone just wants to "feel" installed — then wrapping it in Electron mostly buys you weight and update headaches. Be honest about which side of that line you're on before you install anything. The desktop is for apps that need to touch the machine, not for apps that want a fancier bookmark.

The Two Tools, and the Real Tradeoff

Assuming you genuinely need out of the browser, there are two serious choices, and they represent a real architectural fork — not a matter of taste.

Electron is the established one — VS Code, Slack, Discord are all Electron. Its model is straightforward: it ships an entire copy of Chromium and Node.js inside your app. Your React runs in a real Chrome, and you get full Node in the backend process, so everything you know works exactly as expected. The cost is equally straightforward: because every app bundles its own whole browser, a trivial Electron app starts at a hundred-plus megabytes and a chunk of memory before it does anything. You're shipping a browser per app, times every Electron app the user has installed.

Tauri is the modern challenger with a different bet. Instead of bundling Chromium, it uses the operating system's own built-in webview — the browser engine already on the machine. And instead of Node, its backend is Rust. The payoff is dramatic: Tauri apps are a fraction of the size and memory, often a few megabytes instead of a hundred. The cost is the two edges of that same bet. Using the OS webview means you're rendering on WebKit on macOS, WebView2 on Windows — different engines — so you inherit cross-browser inconsistency as a desktop concern, which is a genuinely strange thing to have to test for in an installed app. And the native backend is Rust, so any serious system-level logic pulls you into a language your React team may not know.

Electron Tauri Renderer bundled Chromium (same OS webview (WebKit / WebView2, everywhere) differs per platform) Backend Node.js Rust App size 100MB+ (ships a browser) a few MB (uses the OS's) You trade size & memory cross-engine testing + Rust

So the choice isn't "which is better," it's which cost you'd rather pay. Electron trades disk and memory for total consistency and a stack your web team already knows. Tauri trades a small footprint for cross-engine testing and a Rust backend. Neither is wrong; they're priced differently, and the right pick depends on whether size or familiarity hurts you more.

The Part That's Actually Different: Two Processes and a Bridge

Whichever you choose, there's one architectural shift that catches web developers off guard, and it's worth understanding because it shapes everything you build. A desktop app is not one environment — it's two, with a guarded door between them.

Your React UI runs in the renderer, which is still fundamentally a web context, sandboxed. The powerful stuff — filesystem, OS APIs, native calls — runs in a separate, privileged backend process (Node in Electron, Rust in Tauri). They can't just call each other's functions; they communicate over an explicit bridge, passing messages across. Your React code doesn't read a file directly — it asks the backend to, and the backend, which actually has the permission, does it and sends the result back.

// Renderer (your React UI): it cannot touch the disk itself. // It asks the privileged backend to do it — Tauri example. import { invoke } from '@tauri-apps/api/tauri'; async function loadNote(id: string) { // Crosses the bridge to the Rust backend, which has real file access. const contents = await invoke<string>('read_note', { id }); return contents; }

This should feel familiar, because it's the same pattern the whole series keeps circling: a sandboxed, untrusted frontend asking a privileged, trusted backend to do the dangerous thing — exactly like the client/server split in auth, just moved onto one machine. The renderer is the browser; the backend process is your server; the bridge is the API between them. Treat that boundary with the same seriousness — validate what crosses it, expose only the specific operations you mean to — and a desktop app stops feeling exotic and starts feeling like a client/server app you happen to ship in one installer.

How I'd Approach It

Strip it to decisions:

  • Ask what you gain, not whether you can. If you don't need filesystem, OS integration, or true offline, the desktop is a heavier browser tab. Don't ship one for a fancy bookmark.
  • The desktop is for touching the machine. Deep file access, tray/menus/global shortcuts, native resources, first-class offline — that's the whole reason to leave the browser.
  • Electron vs Tauri is a cost choice, not a quality one. Electron: big and memory-hungry, but consistent and web-stack-familiar. Tauri: tiny, but cross-engine testing and a Rust backend.
  • It's two processes with a bridge. Your React renderer asks a privileged backend to do the powerful things. Treat that bridge like a client/server boundary, because it is one.

The thing I want you to take from this is that "turn my React app into a desktop app" is the easy, uninteresting half. The wrapper is a solved afternoon. The real work — and the only justification for the extra weight and the two-process complexity — is the native power you reach for once you're out of the sandbox. Go desktop when your app needs the machine. Stay in the tab when it doesn't. And when you do go, remember you didn't escape the client/server split, you just packaged both halves into one window.

The next article stays off the web but changes machines entirely: React Native and mobile — where "same code, new platform" gets far more honest about what actually carries over and what doesn't.

If you're weighing a desktop build and can't tell whether you truly need to leave the browser, that's the exact question worth answering first — and it's usually clearer than it feels. Tell me what native capability you're reaching for and I'll tell you if the desktop is really the only place to get it.

Found this helpful?

Let's discuss your project needs.

Get in touch