Skip to main content
Back to blog

Why I prefer Tauri over Electron for desktop apps

·5 min readWeb Dev

Electron works. Slack, VS Code, Discord, Figma. Some of the most popular desktop apps run on it. But every Electron app ships an entire Chromium browser and a Node.js runtime. That is why Slack uses 500MB of RAM to display chat messages.

Tauri takes a different approach. It uses the operating system's native webview instead of bundling Chromium, and it uses Rust for the backend instead of Node.js. The result is dramatically smaller, faster, and lighter applications.

The numbers

A minimal Electron app ships at around 150-200MB. The same app built with Tauri is 3-10MB. That is not a typo. The difference is that Electron bundles Chromium (~120MB) and Node.js (~30MB) with every application, while Tauri uses the webview that is already installed on the user's system (WebView2 on Windows, WebKit on macOS/Linux).

Memory usage follows the same pattern. A basic Electron app idles at 80-150MB of RAM. The Tauri equivalent uses 20-40MB. When you are running multiple desktop apps throughout the day, this adds up.

How Tauri works

Your frontend is still HTML, CSS, and JavaScript (or TypeScript). You can use React, Svelte, Vue, or any other framework you want. The frontend runs in the OS native webview, not a bundled browser.

The backend is Rust. Instead of Node.js handling system access, file I/O, and native integrations, Tauri exposes a Rust API that your frontend can call. Rust is fast, memory-safe, and compiles to a small native binary.

The communication between frontend and backend happens through a command system:

// src-tauri/src/lib.rs
#[tauri::command]
fn read_config(path: String) -> Result<String, String> {
    std::fs::read_to_string(&path)
        .map_err(|e| e.to_string())
}
// Frontend
import { invoke } from "@tauri-apps/api/core";
 
const config = await invoke<string>("read_config", {
  path: "/home/user/.config/myapp/config.toml",
});

You define commands in Rust, and your frontend calls them with invoke. Type-safe, fast, and no Node.js in the loop.

Setting up a Tauri project

pnpm create tauri-app my-app

The CLI asks for your frontend framework preference and scaffolds everything. The project structure looks like:

my-app/
  src/              # Frontend (React, Svelte, etc.)
  src-tauri/
    src/
      lib.rs        # Rust backend commands
      main.rs       # App entry point
    Cargo.toml      # Rust dependencies
    tauri.conf.json  # App configuration
  package.json

You develop the frontend like any web app (pnpm dev), and Tauri handles the native window, system tray, file access, and everything else.

What Tauri does well

Auto-updates. Tauri has a built-in updater that handles downloading and applying updates. No custom update infrastructure needed.

System tray. Native system tray support with menus and click handlers. This is surprisingly annoying to do in Electron.

File system access. Read and write files through the Rust backend with proper permission scoping. You define exactly which directories the app can access.

Multi-window support. Create multiple windows, each with their own frontend. Useful for settings panels, popups, or dashboard layouts.

Cross-platform builds. Build for Windows, macOS, and Linux from a single codebase. The CI/CD GitHub Action they provide handles all three platforms.

The Rust learning curve

This is the honest downside. If you do not know Rust, there is a learning curve for the backend. The borrow checker, lifetimes, and Rust's ownership model are unfamiliar if you come from JavaScript.

That said, for most desktop apps, the Rust code is minimal. You write commands that handle file I/O, system calls, and data processing. The complex UI logic stays in your frontend framework where you are already comfortable. I found that I could build useful Tauri apps with basic Rust knowledge and learn more as I needed it.

When Electron is still the better choice

If you need full Node.js compatibility (for example, your app depends heavily on npm packages that use native bindings), Electron is easier. If your team has no Rust experience and the app needs to ship fast, Electron's pure JavaScript stack has less friction.

If you are building something where binary size and memory usage do not matter (internal enterprise tools, for example), Electron's maturity and ecosystem are advantages.

Why I switched

I built a small utility app in Electron first. It worked fine but felt wrong shipping a 180MB app that used 120MB of RAM to display a simple dashboard. I rebuilt it in Tauri and the binary was 6MB, used 25MB of RAM, and started in under a second. The user experience was identical, but the resource footprint was not even comparable.

For any new desktop app I build, Tauri is the default. The frontend stays in the web stack I already know, the Rust backend handles the parts that need to be fast and native, and the final product feels like a proper native application rather than a website in a wrapper.

Sources

Enjoying the blog? Subscribe via RSS to get new posts in your reader.

Subscribe via RSS