Tauri 2.0 Project Setup for Production: Capabilities, Plugins, the Real Structure | Ep1

0views
C
CelesteAI
Description
Episode 1 of Tauri Patterns for Production — the series for developers who've built a Tauri demo and want to ship a real desktop app. Source code: https://github.com/GoCelesteAI/tauri_stock_watcher Tauri 2.0 changed the foundation. The 1.x allowlist is replaced by capabilities — JSON files that grant exact permissions per window. Plugins are now first-class — most platform features (opener, fs, dialog, http, sql, notification, updater) ship as opt-in plugins instead of being built-in. This episode tours the project structure every production Tauri 2 app starts from. What You'll Learn: - The two-half project layout: src/ for the React frontend, src-tauri/ for the Rust backend, with a strict separation that keeps the toolchain boundaries clean. - The Tauri 2.0 capability model: each capability is a JSON file under src-tauri/capabilities/ listing exact permissions (core:default, opener:allow-open-url, etc.) for which windows. Replaces the 1.x global allowlist. - The plugin-first architecture: tauri = "2" is the minimal core; everything else (tauri-plugin-opener = "2", tauri-plugin-fs, etc.) is opt-in. Pull only what you need. - The Rust entry point: #[tauri::command] marks any Rust function as JavaScript-callable; invoke_handler registers it; tauri::Builder::default() chains plugins, the handler, and runs the app. - The frontend bridge: invoke("command_name", { args }) from @tauri-apps/api/core returns whatever the Rust side returned, fully typed if you set up TypeScript right. - Production bundling: pnpm tauri build produces .app + .dmg on macOS, .msi on Windows, .deb + .AppImage on Linux — release-ready outputs, covered in detail in episode 8. Timestamps: 0:00 - Intro — Episode 1 starts here 0:23 - Preview — capabilities, plugins, the new model 1:10 - Setup walkthrough — scaffold, install, verify Tauri 2+ 2:00 - Project structure: src/ and src-tauri/ 2:15 - Frontend dependencies (package.json) 2:30 - Rust backend (Cargo.toml — tauri = "2", plugins) 2:45 - Window config + bundling (tauri.conf.json) 3:05 - Capabilities — the new Tauri 2 permission model 3:20 - Rust entry point + invoke handler (lib.rs) 3:50 - Frontend invoke() pattern (App.tsx) 4:25 - Production build output 4:38 - Live demo — the running Stock Watcher app 5:00 - Recap 5:50 - End screen Key Takeaways: 1. Two halves, never mix. src/ is the React frontend (TypeScript, Vite); src-tauri/ is the Rust backend (Cargo). Tauri keeps them strictly separated. The bridge between them is invoke() on the JS side and #[tauri::command] on the Rust side. Trying to import Rust crates from frontend code (or vice versa) is a category error. 2. Capabilities replaced the 1.x allowlist. In Tauri 1.x you'd set a global allowlist in tauri.conf.json listing every API surface. In Tauri 2.0, each capability is a separate JSON file under src-tauri/capabilities/ granting specific permissions to specific windows. The default file default.json ships with core:default (basic core permissions) plus whatever plugins you've added. This is more verbose but vastly more secure — every permission is explicit. 3. Plugins are first-class. The Tauri 2 core (tauri = "2" in Cargo.toml) is minimal. File system access, HTTP, dialogs, OS info, notifications, updater, SQL — all of these are opt-in plugins (tauri-plugin-fs, tauri-plugin-http, etc.). You install only the ones you need, and each one has its own JS API and capability permissions. This dramatically reduces the bundled binary size for apps that don't need everything. 4. #[tauri::command] + invoke_handler is the IPC surface. Annotate any async or sync Rust function with #[tauri::command], register it via tauri::generate_handler![fn1, fn2] passed to invoke_handler on the builder. From the frontend, call await invoke("fn_name", { args }) from @tauri-apps/api/core (typed via the generic parameter). We'll go deep on IPC patterns in episode 2. 5. pnpm tauri build is the production output. Generates platform-specific bundles per the bundle.targets config: .app and .dmg on macOS, .msi on Windows, .deb and .AppImage on Linux. The output is a signed-and-notarized release artifact (once you've configured signing — covered in episode 7). The release binary is ~5-15 MB depending on plugins included, vs ~150 MB for an equivalent Electron app. This channel is run by Claude AI. Tutorials AI-produced; reviewed and published by Codegiz. Source code at codegiz.com. #Tauri #Tauri2 #Rust #DesktopApp #React #TypeScript #ClaudeAI --- Generated by Claude AI · part of the Tauri Patterns for Production series
Back to tutorials

Duration

Added to Codegiz

May 10, 2026

📖 Read the articleOpen in YouTube