cloudparts

Cross-platform desktop apps

Write a Windows, macOS and Linux app mostly once: a framework either ships its own browser engine, borrows the web view the operating system already has, or draws the interface itself, while your code runs natively behind it.

3 technologies on this page ↓

How it works

A native desktop app is written against each platform’s own UI toolkit, so supporting Windows, macOS and Linux means three front ends. Cross-platform frameworks share one front end and differ mainly in what draws it. Electron embeds Chromium and Node.js into the app’s binary. Its main process runs in Node.js, creates windows and handles menus, dialogs and tray icons; each window is a renderer process that shows ordinary HTML, CSS and JavaScript, the same multi-process design as a browser. Because every app carries its own browser, it looks and behaves the same everywhere, but even an empty app is large: Firezone measured about 100 MB for Electron’s default build. Tauri and Wails keep the web front end but use the web view the operating system already has, which Tauri reaches through its WRY library: WebView2 on Windows, WKWebView on macOS and WebKitGTK on Linux. The back end is a native program, Rust for Tauri and Go for Wails, and the page calls it through a message channel (Tauri’s IPC) that the core can filter. A minimal Tauri app can be under 600 KB, but the same HTML now renders in three different engines whose versions depend on the user’s system. Dioxus desktop uses the same system web view through WRY, with the application logic running as native Rust. A third group draws every pixel itself: Flutter compiles Dart to native Windows, macOS and Linux apps with its own widgets, and Dioxus Native renders HTML and CSS on the GPU with its own engine, Blitz, so no web view is involved. Whichever way it is drawn, each platform still gets its own installer (.msi or .exe, .dmg or .app, .deb, .rpm or AppImage), usually built on that platform and signed with that platform’s certificates.

Think of it as

Three ways to furnish holiday flats in different countries. Electron ships the same furniture in a container to every flat, so they all look identical and the container costs a fortune. Tauri uses whatever furniture each landlord already has and brings only the paintings. A framework with its own renderer brings a carpenter who builds the same furniture on site.

Reach for it when

  • One team must ship the same app on Windows, macOS and Linux, and its interface can be built from web technologies or one widget set
  • A web team building a desktop client: Electron, Tauri and Wails reuse HTML, CSS and a JavaScript framework
  • Small downloads and low memory matter, and you can test on each platform’s web view: a system-web-view framework such as Tauri
  • The app must render exactly the same everywhere and use the newest web features on old operating systems: Electron’s bundled Chromium

Think twice when

  • The product works as a website or a progressive web app; a desktop wrapper adds installers, updates and code signing for every platform
  • Pixel-identical rendering on a system-web-view framework: WebView2, WKWebView and WebKitGTK are different engines, and on Linux the WebKitGTK version depends on the distribution release
  • Deep integration with one platform’s look and features, such as a macOS-only utility: the native toolkit is less work than bridging to it

A real example

Firezone, a remote-access product, needed GUI clients for Windows and Linux, and its networking library, connlib, was already written in Rust. The team chose Tauri: the GUI is web code, the back end is “just more Rust” calling connlib, and the tray icon, notifications and self-updates came built in. The Windows client reached beta in about two months. Their installers are 8 MB on Windows and 12 MB on Linux, against about 100 MB for a default Electron app, and the GUI idles at about 100 MB of RAM. The cost showed on Linux: Ubuntu 20.04, 22.04 and 24.04 share no WebKitGTK version, so one .deb can’t cover all three, and on Windows the WebView2 installer sometimes hangs in their CI runners.

Technologies

Specific products, and what each does differently.

Three ways to draw the window#

The approaches differ mainly in which engine renders the interface, and what the app has to ship.

Bundled browser engineSystem web viewOwn renderer
ExamplesElectronTauri, Wails, Dioxus desktopFlutter, Dioxus Native
LanguageJavaScript or TypeScript, with Node.js in the main processHTML, CSS and JavaScript (or Rust compiled to Wasm) for the UI; Rust or Go for the back endDart; Rust with HTML and CSS
What draws the screenChromium, shipped inside every appWebView2 on Windows, WKWebView on macOS, WebKitGTK on LinuxThe framework’s own engine: Flutter’s widgets, or Blitz on the GPU
SizeAbout 100 MB for a default buildUnder 600 KB for a minimal Tauri app; under 5 MB typical for Dioxus desktopDepends on the engine shipped in the app
Trade-offSame engine and newest web features everywhere, at the cost of size and memorySmall and quick to download, but three engines to test, with versions set by the user’s systemLooks the same everywhere without a browser, but the platform’s controls are re-implemented; Blitz doesn’t support all of CSS yet
  • All three still produce one installer per platform, built and signed for that platform.

Often confused with

Where it came from2015–2025

Electron began as Atom Shell, the framework the Atom editor was built on, and was renamed Electron in April 2015. Its 1.0 release, on 11 May 2016, listed apps such as Slack, GitKraken and Nylas’s email client, and it became the default way to turn a web app into a desktop app: one JavaScript codebase, with Chromium and Node.js embedded in the binary.

Shipping a browser with every app made downloads large, and later frameworks borrowed the browser the operating system already had. Wails did this for Go programs, using native rendering engines with no embedded browser. Tauri did it for Rust: 1.0 shipped on 19 June 2022 after an independent security audit, with its code owned by the Commons Conservancy, and its announcement put the cost of large downloads in network energy and CO₂. Tauri 2.0, on 2 October 2024, added iOS and Android and replaced its allowlist with a permissions and capabilities system.

A third line drew the interface itself. Flutter reached stable Windows support with version 2.10 on 4 February 2022. Dioxus, first released in January 2022 as a React-like Rust UI library for web, desktop and mobile, shipped Dioxus Native in September 2025: a GPU renderer built on its own HTML and CSS engine, Blitz, so a Rust app can show HTML and CSS without any web view.

Why it’s built this way

Bundle the browser
Electron wanted web developers to build desktop apps with one codebase. Shipping Chromium with Node.js means every app runs on the same engine, whatever the user has installed.
Use the system web view
Bundled browsers made downloads huge; Firezone cites Electron’s large download sizes as the reason it looked elsewhere. Tauri links the platform’s web view at run time instead, which keeps a minimal app under 600 KB.
A native core that guards the web view
Tauri’s core process is the only part with full access to the operating system, and all messages from the web view pass through it, so the app can grant each window only the permissions it needs.
Draw without a browser
A web view brings platform differences and a browser’s overhead. Flutter and Dioxus Native render with their own engines, so the interface is the same on every system and needs no web view at all.

Timeline

  1. 2015

    Atom Shell is renamed Electron in April

  2. 2016

    Electron 1.0 released on 11 May

  3. 2022

    Dioxus 0.1 in January; Flutter for Windows stable in February; Tauri 1.0 in June

  4. 2024

    Tauri 2.0 adds iOS and Android on 2 October

  5. 2025

    Dioxus 0.7 ships Dioxus Native, a GPU renderer with no web view

Sources10

Improve this page on GitHub