Tauri Fundamentals
Tauri 2.0 architecture, Rust backend with webview frontend, project setup with Cargo and npm, development workflow, and build targets for Windows, macOS, Linux, iOS, and Android.
You are an expert in Tauri 2.0 desktop and mobile application development, covering architecture, project setup, and the full development lifecycle. ## Key Points - **Treating Tauri like Electron**: Expecting Node.js APIs to be available in the frontend process. Tauri's frontend is a pure webview -- use Tauri commands or plugins for system access. - **Putting business logic in the frontend**: Heavy computation or data processing belongs in Rust commands, not in the webview where it blocks the UI thread. - **Ignoring platform differences**: WebView2 (Windows), WebKit (macOS), and WebKitGTK (Linux) have rendering differences. Test on all target platforms early. - **Skipping the permission system**: Tauri 2.0 uses capability-based permissions. Requesting blanket permissions defeats the security model. - **Building without release profile**: Debug builds are dramatically slower. Always test with `--release` before benchmarking or shipping. 1. Starts the frontend dev server (Vite by default) 2. Compiles the Rust backend 3. Opens the app window pointing to the dev server 4. Watches for Rust changes and recompiles 5. Frontend hot-reloads via Vite HMR ## Quick Example ```bash # Generate all required icon sizes from a single 1024x1024 PNG cargo tauri icon src-tauri/icons/app-icon.png ```
skilldb get tauri-skills/Tauri FundamentalsFull skill: 283 linesTauri Fundamentals — Tauri 2.0 Development
You are an expert in Tauri 2.0 desktop and mobile application development, covering architecture, project setup, and the full development lifecycle.
Core Philosophy
Tauri takes the opposite approach from Electron. Instead of bundling Chromium and Node.js with every app, Tauri uses the operating system's native webview (WebView2 on Windows, WebKit on macOS/Linux) and a Rust backend. This produces binaries that are typically 5-10 MB instead of 150+ MB, with significantly lower memory usage. The tradeoff is that you must handle cross-platform webview differences and write your backend logic in Rust rather than JavaScript.
The Tauri 2.0 architecture splits cleanly: the Rust "core" process handles system access, file I/O, and heavy computation, while the webview "frontend" process handles UI rendering. Communication between them flows through a typed IPC bridge. This separation enforces a security boundary -- the frontend cannot directly access the filesystem or network without explicit permission from the Rust side.
Design your app around this split from the start. Put business logic, data processing, and system interactions in Rust commands. Keep the frontend focused on presentation and user interaction. Resist the temptation to tunnel everything through JavaScript -- Rust's performance and safety make it the right place for anything beyond UI rendering.
Anti-Patterns
- Treating Tauri like Electron: Expecting Node.js APIs to be available in the frontend process. Tauri's frontend is a pure webview -- use Tauri commands or plugins for system access.
- Putting business logic in the frontend: Heavy computation or data processing belongs in Rust commands, not in the webview where it blocks the UI thread.
- Ignoring platform differences: WebView2 (Windows), WebKit (macOS), and WebKitGTK (Linux) have rendering differences. Test on all target platforms early.
- Skipping the permission system: Tauri 2.0 uses capability-based permissions. Requesting blanket permissions defeats the security model.
- Building without release profile: Debug builds are dramatically slower. Always test with
--releasebefore benchmarking or shipping.
Project Setup
Prerequisites
Install Rust via rustup and Node.js (18+). On Linux, install WebKitGTK and related system dependencies:
# macOS -- Xcode command line tools
xcode-select --install
# Ubuntu/Debian
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
# Windows -- WebView2 is included in Windows 10/11
# Install Rust from https://rustup.rs
Creating a New Project
# Using create-tauri-app (recommended)
npm create tauri-app@latest my-app
cd my-app
# Or with Cargo
cargo install create-tauri-app
cargo create-tauri-app my-app
The scaffolder asks for your frontend framework (React, Vue, Svelte, Solid, Vanilla, etc.) and package manager.
Project Structure
my-app/
├── src-tauri/ # Rust backend
│ ├── Cargo.toml # Rust dependencies
│ ├── tauri.conf.json # Tauri configuration
│ ├── capabilities/ # Permission definitions
│ │ └── default.json
│ ├── src/
│ │ ├── main.rs # Entry point (or lib.rs)
│ │ └── lib.rs # Command definitions
│ ├── icons/ # App icons
│ └── gen/ # Generated platform code
├── src/ # Frontend source
│ ├── main.ts
│ └── App.tsx
├── package.json
└── vite.config.ts
Configuration (tauri.conf.json)
{
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-cli/schema.json",
"productName": "My App",
"version": "0.1.0",
"identifier": "com.mycompany.myapp",
"build": {
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:5173",
"beforeBuildCommand": "npm run build",
"frontendDist": "../dist"
},
"app": {
"title": "My App",
"windows": [
{
"label": "main",
"width": 1024,
"height": 768,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": "default-src 'self'; script-src 'self'"
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
Development Workflow
Running in Development
# Start dev server with hot reload (frontend) and Rust recompilation
npm run tauri dev
# Or directly with Cargo
cargo tauri dev
# With specific frontend framework dev server
cargo tauri dev --port 3000
The dev workflow:
- Starts the frontend dev server (Vite by default)
- Compiles the Rust backend
- Opens the app window pointing to the dev server
- Watches for Rust changes and recompiles
- Frontend hot-reloads via Vite HMR
Building for Production
# Build for current platform
npm run tauri build
# Build specific bundle type
cargo tauri build --bundles deb,appimage # Linux
cargo tauri build --bundles msi,nsis # Windows
cargo tauri build --bundles dmg,app # macOS
# Build with debug info
cargo tauri build --debug
Build Targets
| Platform | Bundle Types | Notes |
|---|---|---|
| Windows | MSI, NSIS, EXE | WebView2 auto-installed if missing |
| macOS | DMG, .app bundle | Universal binary (Intel + Apple Silicon) |
| Linux | AppImage, deb, rpm | Requires WebKitGTK at runtime |
| iOS | .ipa | Via cargo tauri ios build |
| Android | .apk, .aab | Via cargo tauri android build |
Basic Application Structure
Rust Entry Point (src-tauri/src/lib.rs)
use tauri::Manager;
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! Welcome to Tauri.", name)
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.setup(|app| {
// Initialization logic here
let window = app.get_webview_window("main").unwrap();
window.set_title("My Tauri App")?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Frontend Invocation
import { invoke } from "@tauri-apps/api/core";
async function greetUser() {
const message = await invoke<string>("greet", { name: "World" });
console.log(message); // "Hello, World! Welcome to Tauri."
}
Cargo Dependencies (src-tauri/Cargo.toml)
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
[build-dependencies]
tauri-build = { version = "2", features = [] }
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s" # Optimize for size
strip = true
Icon Generation
# Generate all required icon sizes from a single 1024x1024 PNG
cargo tauri icon src-tauri/icons/app-icon.png
Debugging
# Open webview devtools in dev mode
# On macOS: Cmd+Option+I
# On Windows/Linux: Ctrl+Shift+I (or F12)
# Enable Rust logging
RUST_LOG=debug cargo tauri dev
# Build with debug symbols for release
cargo tauri build --debug
Environment Detection
fn run() {
tauri::Builder::default()
.setup(|app| {
if cfg!(debug_assertions) {
// Development mode
println!("Running in development mode");
} else {
// Production mode
println!("Running in production mode");
}
// Check platform
if cfg!(target_os = "macos") {
println!("Running on macOS");
} else if cfg!(target_os = "windows") {
println!("Running on Windows");
} else if cfg!(target_os = "linux") {
println!("Running on Linux");
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Install this skill directly: skilldb add tauri-skills
Related Skills
Tauri Commands
Rust commands with the invoke pattern, argument passing, return types, async commands, error handling, state management, and type safety between Rust and TypeScript in Tauri 2.0.
Tauri Distribution
Distributing Tauri applications including installers for MSI, DMG, AppImage, and deb, auto-update with the built-in updater, code signing for Windows and macOS, CI/CD builds, and cross-compilation.
Tauri Frontend
Frontend integration with Tauri 2.0 including React, Vue, Svelte, and Solid frameworks, Vite configuration, asset handling, window management, multiple windows, and webview communication.
Tauri Mobile
Tauri 2.0 mobile development for iOS and Android, including platform-specific code, mobile plugins, testing on simulators and devices, and app store distribution.
Tauri Patterns
Common Tauri 2.0 patterns: system tray apps, menu bar apps, file handling, SQLite database integration, IPC communication patterns, background tasks, and single-instance enforcement.
Tauri Plugins
Tauri 2.0 plugin system including official plugins for filesystem, shell, dialog, notification, HTTP, clipboard, updater, and deep-link, plus community plugins and writing custom plugins.