DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

I Shipped a 600 KB Native Desktop App with the Same HTML I'd Put on Vercel

🔗 Code: https://github.com/dev48v/tauri-from-zero
🧠 3-tier learning page: https://dev48v.infy.uk/tech/day43-tauri.html

Day 43 of my TechFromZero series. A new technology every day, every line of code explained.

Today: Tauri 2 — the Rust + native-webview framework for shipping desktop apps from web tech. Same HTML/CSS/JS you'd put on Vercel, but bundled as a 600 KB native binary instead of a URL.

For comparison: an equivalent Electron app is about 120 MB. Tauri is 200× smaller.


Why this matters

If you have VS Code + Slack + Discord + Notion + Spotify open on your laptop right now, that's five separate Chromium runtimes eating RAM. Every Electron app ships its own browser. The cost compounds.

Tauri's bet: every modern OS already ships a high-quality web renderer. WebView2 (Edge Chromium) on Windows. WKWebView (Safari) on macOS. WebKitGTK on Linux. Tauri's Rust core wraps these and skips the runtime tax entirely.

Electron Tauri 2
Binary size ~120 MB ~600 KB
RAM idle ~250 MB ~30 MB
Cold start ~700 ms ~80 ms
Security default Node primitives exposed Nothing exposed (allowlist opt-in)
Frontend Any web stack Any web stack

The frontend code is identical. The shipping is the only thing that changes.


How it works in 3 ideas

Idea 1 — Native window wraps a webview

Tauri's Rust core (wry crate) opens an OS-native window and points the OS's webview at your HTML. From the user's perspective it's a native app. From your code's perspective it's still a browser tab.

Idea 2 — Bridge JS ↔ Rust via invoke()

Annotate any Rust function with #[tauri::command] and JS can call it:

#[tauri::command]
fn get_cpu_count() -> usize {
    std::thread::available_parallelism()
        .map(|n| n.get())
        .unwrap_or(1)
}
Enter fullscreen mode Exit fullscreen mode

From the frontend:

import { invoke } from "@tauri-apps/api/core";
const cpus = await invoke("get_cpu_count");
Enter fullscreen mode Exit fullscreen mode

Args + return are serialized as JSON across the bridge. Use Rust for everything the browser sandbox can't reach: filesystem, system info, OS notifications, clipboard, native dialogs, IPC, anything in the Rust ecosystem.

Idea 3 — Allowlist security model

Electron exposes Node.js to the JS layer — any compromised npm dependency can read your home directory. Tauri inverts that: NOTHING is exposed unless you explicitly enable it in tauri.conf.json:

{
  "plugins": {
    "fs": { "scope": ["$HOME/Documents/*"] },
    "shell": { "open": true }
  }
}
Enter fullscreen mode Exit fullscreen mode

The surface area is the part you opt into. Default is zero. This is a much safer default for a downloadable binary.


Build it in 30 minutes

# 1. Install Rust (one time)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 2. Scaffold a Tauri app
npm create tauri-app@latest tauri-from-zero
cd tauri-from-zero
npm install

# 3. Run in dev mode (opens native window)
npm run tauri dev

# 4. Build release binary for your OS
npm run tauri build
Enter fullscreen mode Exit fullscreen mode

First cargo build takes ~5 minutes (the Rust crate graph). Subsequent builds are seconds.

The release binary lands in src-tauri/target/release/bundle/:

  • macOS → .app + .dmg
  • Windows → .exe + .msi
  • Linux → .AppImage + .deb + .rpm

Wire up GitHub Actions with the official tauri-apps/tauri-action and one git push builds all three from a single CI matrix.


What this unlocks

Three distributions, one frontend codebase:

  1. 🌐 Website — same HTML/JS on Vercel
  2. 🪟 Desktop app — Tauri (this article)
  3. 📱 Mobile app — Tauri Mobile (in beta)

The Indie hacker dream: write the UI once, distribute everywhere.

Mass-market apps shipping on Tauri today include Spacedrive (file manager), Pot (translator), Mailspring (email client), and dozens more on https://tauri.app/showcase.


What's NOT in this article

  • Auto-updates — Tauri ships an updater plugin (signed binaries, delta updates). Real product needs this.
  • Multi-window — Tauri can spawn multiple OS windows for the same app instance.
  • Sidecar binaries — Bundle external CLIs (yt-dlp, ffmpeg) and call from Rust.
  • Plugin ecosystem — Tauri has plugins for SQL, store, notifications, deep links, biometrics, more.

The 8 commits in the repo are the floor. Everything else is layers on top.


Try it now

git clone https://github.com/dev48v/tauri-from-zero
cd tauri-from-zero
npm install
npm run tauri dev
Enter fullscreen mode Exit fullscreen mode

Or open the 3-tier learning page on the showcase site:
https://dev48v.infy.uk/tech/day43-tauri.html


What's next in TechFromZero

Day 44 picks tomorrow. Probably one of: Convex (reactive backend), TanStack Start (new SSR framework), View Transitions API, or Bun + Elysia.

🌐 All days: https://dev48v.infy.uk/techfromzero.php

Top comments (0)