# Tauri — User Guide

## 1. Quick Start

Tauri is a framework for building tiny, secure applications for desktop and mobile platforms using web technologies (HTML, CSS, JavaScript) for the frontend and Rust for the backend. It produces small, fast binaries by leveraging the operating system's native webview rather than bundling a browser engine.

**Key features:**

- Cross-platform desktop apps (Windows, macOS, Linux) and mobile (Android, iOS)
- Tiny binary sizes — uses OS-native webview (WebView2, WebKitGTK, WKWebView)
- Rust backend with secure IPC bridge to JavaScript frontend
- Any web framework (React, Vue, Svelte, SolidJS, vanilla JS)
- Fine-grained security via capability-based permissions (ACL)
- System tray icons, native menus, multi-window and multi-webview support
- Built-in app bundling for all target platforms (NSIS, MSI, DMG, AppImage, .deb, .rpm)
- Official plugin ecosystem for filesystem, HTTP, notifications, clipboard, and more

**Prerequisites:** Rust 1.77.2+, Node.js 10+, platform-specific dependencies (see Installation)

```bash
npm create tauri-app@latest
```

```text
✔ Project name · my-tauri-app
✔ Choose which language to use for your frontend · TypeScript / JavaScript
✔ Choose your package manager · pnpm
✔ Choose your UI template · Svelte
✔ Choose your UI flavor · TypeScript

Template created! To get started run:
  cd my-tauri-app
  pnpm install
  pnpm tauri dev
```

> [!TIP]
> The `create-tauri-app` scaffolder supports React, Vue, Svelte, SolidJS, Angular, vanilla JS, and more. Pick whatever you know best — Tauri is frontend-agnostic.

**What to try next:**

- Run `pnpm tauri dev` for hot-reloading development
- Edit `src-tauri/src/main.rs` to add Rust commands
- Run `pnpm tauri build` to produce release binaries and installers

## 2. Installation

### System Requirements

| Requirement | Minimum |
|---|---|
| Rust | 1.77.2 (stable) |
| Node.js | 10+ (for `@tauri-apps/cli`) |
| Package manager | npm, pnpm, yarn, or bun |

### Platform Prerequisites

=== "Windows"
    - Microsoft Visual Studio C++ Build Tools (via Visual Studio Installer)
    - WebView2 runtime (pre-installed on Windows 10 1803+ and Windows 11)
    - Rust target: `x86_64-pc-windows-msvc` or `aarch64-pc-windows-msvc`

=== "macOS"
    - Xcode Command Line Tools: `xcode-select --install`
    - For iOS development: full Xcode installation
    - Rust target: `x86_64-apple-darwin` and/or `aarch64-apple-darwin`

=== "Linux"
    - System libraries (Debian/Ubuntu):
    ```bash
    sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \
      libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
    ```
    - Rust target: `x86_64-unknown-linux-gnu` (glibc) or musl variants

> [!IMPORTANT]
> On Linux, WebKitGTK 4.1+ (`libwebkit2gtk-4.1-dev`) is required. Older WebKitGTK 4.0 packages will not work with Tauri v2.

### Install the Tauri CLI

=== "npm"
    ```bash
    npm install -D @tauri-apps/cli
    ```

=== "pnpm"
    ```bash
    pnpm add -D @tauri-apps/cli
    ```

=== "Cargo"
    ```bash
    cargo install tauri-cli
    ```

=== "cargo-binstall"
    ```bash
    cargo binstall tauri-cli
    ```

### Verify Installation

```bash
cargo tauri --version
```

```text
tauri-cli 2.10.1
```

> [!TIP]
> When installed via npm/pnpm, use `npx tauri` or `pnpm tauri` instead of `cargo tauri`.

### Install Troubleshooting

**Error: `pkg-config` not found (Linux)**

**Cause:** Missing build dependency.

**Solution:**
```bash
sudo apt install pkg-config
```

**Error: WebView2 not found (Windows)**

**Cause:** WebView2 runtime not installed on older Windows versions.

**Solution:** Download the Evergreen Bootstrapper from Microsoft and install it. Tauri can also bundle the WebView2 installer — see the Admin Guide for `bundle.windows.webviewInstallMode` configuration.

**Error: `wasm32-unknown-unknown` target not found**

**Cause:** This target is not needed for Tauri desktop apps.

**Solution:** This error typically comes from another tool. Ensure you're running `cargo tauri build`, not `cargo build` directly.

## 3. Configuration

Tauri applications are configured through `tauri.conf.json` (or `.json5`/`Tauri.toml`) in your `src-tauri/` directory.

### Minimal Configuration

```json
{
  "productName": "my-app",
  "version": "0.1.0",
  "identifier": "com.example.myapp",
  "build": {
    "devUrl": "http://localhost:1420",
    "frontendDist": "../dist"
  },
  "app": {
    "windows": [
      {
        "title": "My App",
        "width": 800,
        "height": 600,
        "resizable": true
      }
    ]
  },
  "bundle": {
    "active": true,
    "targets": "all",
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }
}
```

> [!IMPORTANT]
> The `identifier` field is required and must be unique in reverse domain notation (e.g., `com.company.appname`). The default `com.tauri.dev` is rejected during builds.

### Common Configuration Options

| Key | Type | Purpose |
|---|---|---|
| `productName` | string | App display name |
| `version` | string | App version (semver) |
| `identifier` | string | Unique bundle identifier |
| `build.devUrl` | string | Dev server URL for `tauri dev` |
| `build.frontendDist` | string | Path to built frontend assets |
| `build.beforeDevCommand` | string | Command to run before `tauri dev` |
| `build.beforeBuildCommand` | string | Command to run before `tauri build` |
| `app.windows` | array | Window configurations |
| `app.security.csp` | string | Content Security Policy |
| `app.withGlobalTauri` | boolean | Expose `window.__TAURI__` globally |
| `bundle.active` | boolean | Enable bundling on `tauri build` |
| `bundle.targets` | string/array | Which bundle formats to produce |

### Platform-Specific Configuration

Tauri merges platform-specific config files automatically:

- `tauri.windows.conf.json`
- `tauri.macos.conf.json`
- `tauri.linux.conf.json`
- `tauri.android.conf.json`
- `tauri.ios.conf.json`

### Environment Variables

| Variable | Purpose |
|---|---|
| `TAURI_SIGNING_PRIVATE_KEY` | Private key for update signatures |
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Password for the signing key |
| `TAURI_CONFIG` | JSON config to merge at build time |
| `TAURI_CLI_VERBOSITY` | CLI log verbosity (0-2) |
| `TAURI_DEV_HOST` | Custom host for dev server HMR |
| `TAURI_WEBVIEW_AUTOMATION` | Enable WebDriver automation |
| `TAURI_SKIP_SIDECAR_SIGNATURE_CHECK` | Skip sidecar signature verification |

> [!NOTE]
> See the Admin Guide for the complete configuration reference covering every `tauri.conf.json` field, all Cargo features, and platform-specific bundle settings.

## 4. Core Usage

### CLI Commands

The `cargo tauri` (or `pnpm tauri`) CLI manages your entire development workflow:

| Command | Purpose |
|---|---|
| `cargo tauri init` | Initialize a new Tauri project in an existing frontend |
| `cargo tauri dev` | Run the app in development mode with hot reload |
| `cargo tauri build` | Build the app in release mode and generate bundles |
| `cargo tauri bundle` | Generate bundles from an already-built binary |
| `cargo tauri add <plugin>` | Add an official Tauri plugin to the project |
| `cargo tauri remove <plugin>` | Remove a Tauri plugin |
| `cargo tauri icon <input>` | Generate all required app icons from a source image |
| `cargo tauri info` | Show environment and dependency information |
| `cargo tauri signer` | Manage update signing keys |
| `cargo tauri completions` | Generate shell completions |
| `cargo tauri migrate` | Migrate from Tauri v1 to v2 |
| `cargo tauri plugin` | Scaffold and manage plugin projects |
| `cargo tauri android` | Android development commands |
| `cargo tauri ios` | iOS development commands (macOS only) |
| `cargo tauri inspect` | Inspect build values (e.g., MSI upgrade codes) |
| `cargo tauri permission` | Manage ACL permissions |
| `cargo tauri capability` | Manage ACL capabilities |

### Development Mode

```bash
cargo tauri dev
```

This runs your `build.beforeDevCommand` (e.g., `pnpm dev`), starts the Rust backend, and opens your app in a native window. Changes to frontend code are hot-reloaded. Changes to Rust code trigger a recompile.

> [!TIP]
> Use `cargo tauri dev --target <triple>` to test platform-specific code. For Android: `cargo tauri android dev`. For iOS: `cargo tauri ios dev`.

### Build Options

```bash
cargo tauri build
```

Key flags:

| Flag | Purpose |
|---|---|
| `--debug` | Build with debug profile |
| `--target <triple>` | Cross-compile for a specific target |
| `--features <list>` | Activate Cargo features |
| `--bundles <formats>` | Specific bundle formats (e.g., `nsis,msi`) |
| `--no-bundle` | Compile without bundling |
| `--config <json>` | Merge additional config |
| `--ci` | Skip interactive prompts |
| `--no-sign` | Skip code signing |

### Writing Rust Commands (IPC)

Tauri uses an IPC bridge to let JavaScript call Rust functions. Define commands with the `#[tauri::command]` macro:

```rust
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
```

Call from JavaScript:

```typescript
import { invoke } from '@tauri-apps/api/core';

const greeting = await invoke('greet', { name: 'World' });
console.log(greeting); // "Hello, World!"
```

> [!WARNING]
> Commands are blocked by default in Tauri v2. You must grant permissions via capability files in `src-tauri/capabilities/` for your frontend to invoke them.

### Async Commands

```rust
#[tauri::command]
async fn fetch_data(url: String) -> Result<String, String> {
    // async operations here
    Ok("data".to_string())
}
```

### JavaScript API (`@tauri-apps/api`)

The `@tauri-apps/api` package (v2.10.1) provides TypeScript bindings for interacting with Tauri from JavaScript:

| Module | Purpose |
|---|---|
| `core` | `invoke()` for calling Rust commands |
| `app` | App metadata (`getVersion`, `getName`, `setTheme`, `getBundleType`) |
| `window` | Window management (`Window`, `getCurrent`, `getAll`) |
| `webview` | Webview management |
| `event` | Cross-process event system (`emit`, `listen`) |
| `image` | Image handling for icons |
| `menu` | Application and context menus |
| `tray` | System tray icon management |
| `dpi` | DPI-aware size/position types |
| `path` | Cross-platform path resolution |

```typescript
import { getVersion, getName, setTheme } from '@tauri-apps/api/app';

const version = await getVersion();
const name = await getName();
await setTheme('dark');
```

> [!NOTE]
> The `setTheme()` function is not supported on iOS or Android. The `setDockVisibility()` function is macOS-only. Check platform-specific notes on each API.

### Window Management

Create windows programmatically:

```rust
// Rust
use tauri::Manager;

app.setup(|app| {
    let _window = tauri::WebviewWindowBuilder::new(
        app,
        "secondary",
        tauri::WebviewUrl::App("index.html".into()),
    )
    .title("Secondary Window")
    .inner_size(400.0, 300.0)
    .build()?;
    Ok(())
});
```

```typescript
// JavaScript
import { WebviewWindow } from '@tauri-apps/api/webview';

const webview = new WebviewWindow('secondary', {
  url: 'settings.html',
  title: 'Settings',
  width: 400,
  height: 300,
});
```

### Event System

Emit and listen to events between Rust and JavaScript:

```rust
// Rust: emit to frontend
app_handle.emit("backend-event", "payload data")?;

// Rust: listen from frontend
app.listen("frontend-event", |event| {
    println!("Received: {:?}", event.payload());
});
```

```typescript
// JavaScript
import { emit, listen } from '@tauri-apps/api/event';

await emit('frontend-event', { message: 'hello' });

const unlisten = await listen('backend-event', (event) => {
  console.log(event.payload);
});
```

### System Tray

Enable the `tray-icon` feature in `Cargo.toml`:

```toml
[dependencies]
tauri = { version = "2", features = ["tray-icon"] }
```

```rust
use tauri::tray::TrayIconBuilder;
use tauri::menu::{MenuBuilder, MenuItemBuilder};

fn create_tray(app: &tauri::AppHandle) -> tauri::Result<()> {
    let menu = MenuBuilder::new(app)
        .item(&MenuItemBuilder::with_id("quit", "Quit").build(app)?)
        .build()?;

    TrayIconBuilder::new()
        .menu(&menu)
        .on_menu_event(|app, event| {
            if event.id() == "quit" {
                app.exit(0);
            }
        })
        .build(app)?;
    Ok(())
}
```

> [!NOTE]
> Tray icons are desktop-only (Windows, macOS, Linux). On Linux, the `linux-libxdo` feature enables additional tray icon interactions via `libxdo`.

### Application Menus

```rust
use tauri::menu::{MenuBuilder, SubmenuBuilder, MenuItemBuilder};

let file_menu = SubmenuBuilder::new(app, "File")
    .item(&MenuItemBuilder::with_id("open", "Open").build(app)?)
    .item(&MenuItemBuilder::with_id("save", "Save").build(app)?)
    .separator()
    .item(&MenuItemBuilder::with_id("quit", "Quit").build(app)?)
    .build()?;

let menu = MenuBuilder::new(app)
    .item(&file_menu)
    .build()?;

app.set_menu(menu)?;
```

### Streaming Data with Channels

For sending multiple messages from Rust to JavaScript (progress updates, streaming data):

```rust
use tauri::ipc::Channel;

#[tauri::command]
async fn stream_data(channel: Channel<i32>) -> tauri::Result<()> {
    for i in 0..100 {
        channel.send(i)?;
        tokio::time::sleep(std::time::Duration::from_millis(50)).await;
    }
    Ok(())
}
```

### Window Vibrancy Effects

On macOS and Windows, apply transparency and blur effects:

```rust
use tauri_utils::config::WindowEffectsConfig;

// Applied via webview builder
builder.window_effects(WindowEffectsConfig { /* ... */ });
```

> [!TIP]
> On macOS, the `macos-private-api` feature is required for fullscreen transparency and other private APIs. Enable it with `features = ["macos-private-api"]` in your Cargo.toml.

## 5. Common Tasks

### Adding a Plugin

```bash
cargo tauri add <plugin-name>
```

This command:
1. Adds the Rust crate (`tauri-plugin-<name>`) to `Cargo.toml`
2. Installs the npm package (`@tauri-apps/plugin-<name>`) if applicable
3. Adds the `<name>:default` permission to your capabilities
4. Injects `.plugin(tauri_plugin_<name>::init())` into your `main.rs`/`lib.rs`

> [!TIP]
> Use `cargo tauri add <plugin>@<version>` to pin a specific version. Use `--tag`, `--rev`, or `--branch` flags for git-based installs of official plugins.

### Generating App Icons

```bash
cargo tauri icon app-icon.png
```

```text
[INFO] Appx Creating StoreLogo.png
[INFO] ICNS Creating icon.icns
[INFO] ICO  Creating icon.ico
[INFO] PNG  Creating 32x32.png
...
```

The source image must be square (1024x1024 recommended). SVG input is supported. This generates all platform-specific icon formats: `.ico` (Windows), `.icns` (macOS), `.png` (Linux), and Android adaptive icons with foreground, background, and monochrome layers.

### Building for Production

```bash
cargo tauri build
```

```text
[INFO] Running beforeBuildCommand `pnpm build`
[INFO] Compiling app in release mode...
[INFO] Built application at: src-tauri/target/release/my-app
[INFO] Bundling my-app.msi
[INFO] Finished: src-tauri/target/release/bundle/msi/my-app_0.1.0_x64_en-US.msi
```

### Building a Universal macOS Binary

```bash
cargo tauri build --target universal-apple-darwin
```

> [!IMPORTANT]
> Building a universal macOS binary requires both `aarch64-apple-darwin` and `x86_64-apple-darwin` Rust targets installed: `rustup target add aarch64-apple-darwin x86_64-apple-darwin`.

### Setting Up Mobile Development

**Android:**
```bash
cargo tauri android init
cargo tauri android dev
cargo tauri android build
```

**iOS (macOS only):**
```bash
cargo tauri ios init
cargo tauri ios dev
cargo tauri ios build
```

> [!NOTE]
> Android requires Android Studio and the NDK. The Tauri mobile runtime targets a minimum SDK of 21 (Android 5.0) with `compileSdk` 36. iOS requires Xcode and targets a minimum of iOS 14.0.

### Managing State

Share state between commands using Tauri's managed state:

```rust
use std::sync::Mutex;
use tauri::State;

struct AppState {
    counter: Mutex<i32>,
}

#[tauri::command]
fn increment(state: State<'_, AppState>) -> i32 {
    let mut counter = state.counter.lock().unwrap();
    *counter += 1;
    *counter
}

fn main() {
    tauri::Builder::default()
        .manage(AppState { counter: Mutex::new(0) })
        .invoke_handler(tauri::generate_handler![increment])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
```

### Using the Isolation Pattern

Isolation adds a security layer between your frontend and the Tauri IPC bridge by running a separate, trusted script to validate and sanitize IPC messages.

Enable in `tauri.conf.json`:

```json
{
  "app": {
    "security": {
      "pattern": {
        "use": "isolation",
        "options": {
          "dir": "../isolation-dist"
        }
      }
    }
  }
}
```

And enable the `isolation` Cargo feature:

```toml
tauri = { version = "2", features = ["isolation"] }
```

> [!WARNING]
> The isolation application directory must exist and must contain a file that sets `window.__TAURI_ISOLATION_HOOK__`. Without this hook, the build will fail.

### Creating a Plugin

```bash
cargo tauri plugin new my-plugin
```

This scaffolds a complete plugin project with:
- Rust source (`src/lib.rs`, `src/desktop.rs`, `src/mobile.rs`)
- TypeScript guest bindings (`guest-js/`)
- Build script for permission generation
- Android and iOS platform stubs
- Example app for testing

### Signing Updates

Generate a key pair for auto-updates:

```bash
cargo tauri signer generate -w ~/.tauri/myapp.key
```

Set the environment variables before building:

```bash
export TAURI_SIGNING_PRIVATE_KEY=$(cat ~/.tauri/myapp.key)
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="your-password"
cargo tauri build
```

### File Associations

Register file type associations in `tauri.conf.json`:

```json
{
  "bundle": {
    "fileAssociations": [
      {
        "ext": ["myext"],
        "mimeType": "application/x-myapp"
      }
    ]
  }
}
```

Handle opened files in Rust:

```rust
app.run(|_app, event| {
    if let tauri::RunEvent::Opened { urls } = event {
        for url in urls {
            println!("Opened: {}", url);
        }
    }
});
```

> [!NOTE]
> The `Opened` event is only emitted on macOS, iOS, and Android. On Windows and Linux, file association arguments are passed as command-line arguments.

### Bundling Resources

Include additional files with your application:

```json
{
  "bundle": {
    "resources": ["assets/*", "data/config.json"]
  }
}
```

Access them at runtime:

```rust
use tauri::{Manager, path::BaseDirectory};

let resource_path = app.path().resolve("assets/data.json", BaseDirectory::Resource)?;
```

### Restarting the Application

```rust
app_handle.restart();
```

```typescript
import { relaunch } from '@tauri-apps/api/process';
await relaunch();
```

> [!CAUTION]
> On macOS, the `process-relaunch-dangerous-allow-symlink-macos` feature allows restarting via symlinked paths. This is disabled by default because symlinked binaries could be replaced between restart and re-execution.

### Handling the Android Back Button

```typescript
import { onBackButtonPress } from '@tauri-apps/api/app';

await onBackButtonPress((payload) => {
  if (payload.canGoBack) {
    window.history.back();
  }
});
```

### Custom Protocol for Asset Loading

Enable the `protocol-asset` feature for loading local files through a custom URI scheme:

```toml
tauri = { version = "2", features = ["protocol-asset"] }
```

### Using Multiple Webviews in One Window

Enable the `unstable` feature for multi-webview support within a single window:

```toml
tauri = { version = "2", features = ["unstable"] }
```

```rust
// Create a window with multiple webviews
let window = tauri::window::WindowBuilder::new(app, "main")
    .build()?;
// Attach webviews to the window
```

## 6. Troubleshooting

### Diagnostic Decision Tree

1. **Build fails?** → Run `cargo tauri info` to check environment
2. **Runtime crash?** → Check `src-tauri/` console output for Rust panics
3. **IPC not working?** → Verify permissions in `src-tauri/capabilities/`
4. **Blank window?** → Check `devUrl` or `frontendDist` paths in config
5. **Icons missing?** → Run `cargo tauri icon` with a 1024x1024 source

### Error: `Unable to find your web assets`

**Cause:** The `build.frontendDist` directory doesn't exist because the frontend build hasn't run.

**Solution:**
1. Run your frontend build command first (e.g., `pnpm build`)
2. Verify the `frontendDist` path in `tauri.conf.json` points to the actual output directory

**Prevention:** Set `build.beforeBuildCommand` so Tauri builds your frontend automatically.

### Error: `You must change the bundle identifier`

**Cause:** The default identifier `com.tauri.dev` is not allowed for builds.

**Solution:**
Set a unique identifier in `tauri.conf.json`:
```json
{
  "identifier": "com.yourcompany.yourapp"
}
```

### Error: `The bundle identifier string must contain only alphanumeric characters`

**Cause:** Special characters (other than `-` and `.`) in the `identifier` field.

**Solution:**
Use only `A-Z`, `a-z`, `0-9`, hyphens, and periods in the identifier.

### Error: `runtime already initialized`

**Cause:** Attempting to start the Tauri runtime more than once.

**Solution:**
Ensure `tauri::Builder::default().run()` is only called once in your application entry point.

### Error: `state not found for type`

**Cause:** Calling `State<'_, T>` in a command without registering `T` with `.manage()`.

**Solution:**
```rust
tauri::Builder::default()
    .manage(MyState::new()) // Register your state
    .invoke_handler(tauri::generate_handler![my_command])
```

### Error: `The configured frontendDist is the src-tauri folder`

**Cause:** `frontendDist` points to the Rust project directory instead of the web build output.

**Solution:**
Set `frontendDist` to your actual frontend build output (e.g., `"../dist"` or `"../build"`).

### Error: `frontendDist includes node_modules or src-tauri`

**Cause:** The frontend dist directory contains subdirectories that should not be bundled.

**Solution:**
Isolate your web assets in a clean output directory that doesn't contain `node_modules` or `src-tauri`.

> [!WARNING]
> If `frontendDist` points to a directory that contains `node_modules` or `src-tauri`, the build will fail. Keep your web output in an isolated directory like `dist/` or `build/`.

### Windows Defender False Positive (Issue #2486)

**Cause:** Windows Defender and some antivirus products may flag Tauri executables as potentially unwanted programs. This is a known false positive affecting many Rust-compiled binaries.

**Solution:**
1. Submit the binary to Microsoft for analysis
2. Code-sign your application with a valid certificate
3. Add an exclusion for your build directory during development

**Prevention:** Always code-sign release builds. Signed binaries receive fewer false positives.

### Error: `WebviewWindow is not created at position on macOS` (Issue #12167)

**Cause:** Known bug where windows may not appear at the specified position on macOS.

**Solution:**
Set the position after window creation using the `set_position` API as a workaround.

### Error: `Can't resize devtools sometimes on macOS` (Issue #10523)

**Cause:** Known intermittent bug with the WebKit devtools panel on macOS.

**Solution:**
Close and reopen devtools, or resize the parent window first.

### Error: `Native binding package version mismatch`

**Cause:** The `@tauri-apps/cli` npm package version doesn't match the native binary version.

**Solution:**
```bash
pnpm install @tauri-apps/cli@latest
```

Or delete `node_modules` and reinstall:
```bash
rm -rf node_modules && pnpm install
```

### Error: `failed to run beforeDevCommand`

**Cause:** The command specified in `build.beforeDevCommand` failed to execute.

**Solution:**
1. Verify the command works when run manually
2. Ensure your frontend dev server dependencies are installed
3. Check that the command is appropriate for your package manager

### Error: `The isolation application does not contain a file setting the __TAURI_ISOLATION_HOOK__`

**Cause:** Using the isolation pattern but the isolation dist directory is missing the required hook script.

**Solution:**
Ensure your isolation application (the directory in `app.security.pattern.options.dir`) contains a script that sets `window.__TAURI_ISOLATION_HOOK__`.

### Error: `Library not found` during build

**Cause:** A required system library is not installed.

**Solution:**
Run `cargo tauri info` to check which libraries are detected. Install missing libraries per the platform prerequisites above.

## 7. FAQ

**Q: What frontend frameworks does Tauri support?**

Any framework that produces HTML, CSS, and JavaScript. React, Vue, Svelte, SolidJS, Angular, Preact, vanilla JS, and more all work. Tauri is frontend-agnostic — it just loads a URL or directory of static files into a native webview.

**Q: How is Tauri different from Electron?**

Tauri uses the OS-native webview instead of bundling Chromium, resulting in dramatically smaller binaries (often 5-10 MB vs 100+ MB). The backend is Rust instead of Node.js, providing better performance and memory safety. The trade-off is that webview behavior may vary slightly across platforms.

**Q: Can I use Tauri for mobile apps?**

Yes. Tauri v2 supports Android (SDK 21+) and iOS (14.0+). Use `cargo tauri android dev` and `cargo tauri ios dev` for mobile development.

**Q: How do I pass data between JavaScript and Rust?**

Use the IPC system. Define `#[tauri::command]` functions in Rust and call them from JavaScript with `invoke()` from `@tauri-apps/api/core`. Arguments are serialized as JSON. For streaming data, use channels via `Channel<T>`.

**Q: What config file formats are supported?**

JSON (`tauri.conf.json`) by default. JSON5 (`tauri.conf.json5`) via the `config-json5` Cargo feature, and TOML (`Tauri.toml`) via the `config-toml` feature.

**Q: How do I access the filesystem from JavaScript?**

Use the official `@tauri-apps/plugin-fs` plugin. Install it with `cargo tauri add fs`, then grant appropriate permissions in your capability file. Direct filesystem access from the webview is blocked by default for security.

**Q: Can I have multiple windows?**

Yes. Define multiple windows in `app.windows` in your config, or create them programmatically at runtime using `WebviewWindowBuilder` (Rust) or `new WebviewWindow()` (JavaScript). Each window needs a unique label.

**Q: How do I enable DevTools in production?**

Enable the `devtools` Cargo feature:
```toml
tauri = { version = "2", features = ["devtools"] }
```

> [!CAUTION]
> Do not ship production builds with `devtools` enabled, as it allows users to inspect and modify your application's internals.

**Q: How do permissions and capabilities work?**

Tauri v2 uses a capability-based access control system. Each window/webview is assigned capabilities (in `src-tauri/capabilities/`), and each capability grants specific permissions (like `fs:read`, `app:default`). Commands and APIs are denied by default until explicitly permitted.

**Q: What bundle formats are supported?**

| Platform | Formats |
|---|---|
| Windows | NSIS (`.exe`), MSI (`.msi`) |
| macOS | DMG (`.dmg`), App Bundle (`.app`) |
| Linux | Debian (`.deb`), RPM (`.rpm`), AppImage |
| Android | APK, AAB |
| iOS | IPA |

**Q: How do I update my app automatically?**

Use the `@tauri-apps/plugin-updater` plugin with signed update manifests. Generate a signing key with `cargo tauri signer generate`, set the `TAURI_SIGNING_PRIVATE_KEY` environment variable, and configure your updater endpoint.

**Q: Can I use TypeScript for the Rust commands?**

No, commands must be written in Rust. However, the `specta` feature (opt-in) can auto-generate TypeScript type bindings from your Rust command signatures.

**Q: What is the `app.withGlobalTauri` option?**

When set to `true`, the Tauri API is accessible via `window.__TAURI__` in addition to the module imports. This is useful for scripts that cannot use ES module imports.

**Q: Does Tauri support WebDriver testing?**

Yes. The `tauri-driver` binary is a WebDriver server that proxies to the platform's native WebDriver (msedgedriver on Windows, safaridriver on macOS). Set `TAURI_WEBVIEW_AUTOMATION=true` to enable automation endpoints.

**Q: How do I customize the release profile?**

The workspace `Cargo.toml` sets release defaults: `panic = "abort"`, `codegen-units = 1`, `lto = true`, `opt-level = "s"`, `strip = true`. These optimize for small binary size. Override them in your own `[profile.release]` section if needed.

---

_Generated May 2026 from tauri-apps/tauri at df3fb97. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
