DEV Community

Alex Spinov
Alex Spinov

Posted on

Tauri v2 Has a Free API That Builds Desktop Apps 10x Smaller Than Electron

Tauri v2 builds native desktop apps using web technologies. Your app uses the OS webview instead of bundling Chromium — resulting in 600KB apps instead of 150MB.

Frontend: Any Framework

// src/App.tsx — React, Vue, Svelte, or plain HTML
import { invoke } from "@tauri-apps/api/core";

function App() {
  const [result, setResult] = useState("");

  async function scrape() {
    const data = await invoke("scrape_url", { url: "https://example.com" });
    setResult(data);
  }

  return (
    <div>
      <button onClick={scrape}>Scrape</button>
      <pre>{result}</pre>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Backend: Rust Commands

// src-tauri/src/lib.rs
#[tauri::command]
async fn scrape_url(url: String) -> Result<String, String> {
    let response = reqwest::get(&url).await.map_err(|e| e.to_string())?;
    let html = response.text().await.map_err(|e| e.to_string())?;
    Ok(html)
}

#[tauri::command]
fn read_file(path: String) -> Result<String, String> {
    std::fs::read_to_string(&path).map_err(|e| e.to_string())
}

pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![scrape_url, read_file])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
Enter fullscreen mode Exit fullscreen mode

File System API

import { readTextFile, writeTextFile, readDir } from "@tauri-apps/plugin-fs";
import { open, save } from "@tauri-apps/plugin-dialog";

// Open file dialog
const filePath = await open({ filters: [{ name: "CSV", extensions: ["csv"] }] });
const content = await readTextFile(filePath);

// Save file dialog
const savePath = await save({ defaultPath: "export.json" });
await writeTextFile(savePath, JSON.stringify(data, null, 2));

// Read directory
const entries = await readDir("/home/user/data");
Enter fullscreen mode Exit fullscreen mode

System Tray

use tauri::{SystemTray, SystemTrayMenu, SystemTrayMenuItem, CustomMenuItem};

let tray_menu = SystemTrayMenu::new()
    .add_item(CustomMenuItem::new("scrape", "Start Scraping"))
    .add_native_item(SystemTrayMenuItem::Separator)
    .add_item(CustomMenuItem::new("quit", "Quit"));

let tray = SystemTray::new().with_menu(tray_menu);
Enter fullscreen mode Exit fullscreen mode

Window Management

import { WebviewWindow } from "@tauri-apps/api/webviewWindow";

const newWindow = new WebviewWindow("results", {
  url: "/results",
  title: "Scraping Results",
  width: 800,
  height: 600,
  resizable: true,
});
Enter fullscreen mode Exit fullscreen mode

Notifications

import { sendNotification } from "@tauri-apps/plugin-notification";

sendNotification({
  title: "Scraping Complete",
  body: "1,234 products extracted from 5 sites",
});
Enter fullscreen mode Exit fullscreen mode

App Size Comparison

Framework Hello World Size
Tauri v2 ~600KB
Electron ~150MB
Neutralino ~2MB

Build desktop scraping tools? My Apify tools + Tauri = native data extraction apps.

Custom desktop app? Email spinov001@gmail.com

Top comments (0)