Skip to content
Back to skills

Tauri Migration

ASecurity

Assists users with migrating Tauri applications from v1 to v2 stable, and from v2 beta to v2 stable, covering breaking changes, configuration updates, API migrations, and plugin system changes.

  • 33 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added February 8, 2026
developmentjavascriptrustgojavashellbashapifrontend

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned February 12, 2026

npx -y skills add dchuk/claude-code-tauri-skills --skill tauri-migration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tauri Migration?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tauri Migration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dchuk-tauri-migration/badge)](https://www.skillsdirectory.com/skills/dchuk-tauri-migration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: migrating-tauri-apps
description: Assists users with migrating Tauri applications from v1 to v2 stable, and from v2 beta to v2 stable, covering breaking changes, configuration updates, API migrations, and plugin system changes.
---

# Tauri Migration Guide

This skill covers migrating Tauri applications to v2 stable from either v1 or v2 beta.

## Migration Paths

| Source Version | Target | Complexity |
|----------------|--------|------------|
| Tauri v1.x | v2 stable | High - significant breaking changes |
| Tauri v2 beta | v2 stable | Low - minor breaking changes |

---

## Automated Migration

Both migration paths support automated migration via the Tauri CLI:

```bash
# Install latest CLI first
npm install @tauri-apps/cli@latest

# Run migration
npm run tauri migrate
# or: yarn tauri migrate | pnpm tauri migrate | cargo tauri migrate
```

**IMPORTANT:** The migrate command automates most tasks but is NOT a complete substitute for manual review. Always verify changes after running.

---

## V1 to V2 Migration

### Configuration File Changes

#### BREAKING: Top-Level Structure Changes

**Before (v1):**
```json
{
  "package": {
    "productName": "my-app",
    "version": "1.0.0"
  },
  "tauri": {
    "bundle": { ... },
    "allowlist": { ... }
  }
}
```

**After (v2):**
```json
{
  "productName": "my-app",
  "version": "1.0.0",
  "mainBinaryName": "my-app",
  "identifier": "com.example.myapp",
  "app": { ... },
  "bundle": { ... }
}
```

#### Key Renames

| v1 Path | v2 Path |
|---------|---------|
| `package.productName` | `productName` (top-level) |
| `package.version` | `version` (top-level) |
| `tauri` | `app` |
| `tauri.bundle` | `bundle` (top-level) |
| `tauri.bundle.identifier` | `identifier` (top-level) |
| `tauri.systemTray` | `app.trayIcon` |
| `build.distDir` | `frontendDist` |
| `build.devPath` | `devUrl` |

#### BREAKING: New Required Field

Add `mainBinaryName` matching your `productName` - this is no longer automatic:

```json
{
  "productName": "My App",
  "mainBinaryName": "My App"
}
```

#### Bundle Configuration Reorganization

Platform-specific bundle configs moved under their platform key:

**Before:**
```json
{
  "tauri": {
    "bundle": {
      "dmg": { ... },
      "deb": { ... }
    }
  }
}
```

**After:**
```json
{
  "bundle": {
    "macOS": {
      "dmg": { ... }
    },
    "linux": {
      "deb": { ... }
    }
  }
}
```

#### Updater Configuration

If using the app updater, add to bundle config:

```json
{
  "bundle": {
    "createUpdaterArtifacts": "v1Compatible"
  }
}
```

Use `"v1Compatible"` for existing distributions to maintain backward compatibility.

---

### BREAKING: Allowlist Replaced with Capabilities

The v1 allowlist system is completely replaced with a capability-based ACL system.

#### Creating Capabilities

Create JSON files in `src-tauri/capabilities/`:

**src-tauri/capabilities/default.json:**
```json
{
  "identifier": "default",
  "description": "Default capabilities for the main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "shell:allow-open",
    "dialog:allow-open",
    "fs:allow-read-text-file"
  ]
}
```

The `tauri migrate` command auto-generates capabilities from your v1 allowlist.

---

### Cargo.toml Changes

#### Removed Features

These features no longer exist in v2:
- `reqwest-client`
- `reqwest-native-tls-vendored`
- `process-command-api`
- `shell-open-api`
- `windows7-compat`
- `updater`
- `system-tray`

#### New Features

- `linux-protocol-body` - Custom protocol request body parsing support

### BREAKING: API Module Removal

The entire `api` module is removed. Functionality moved to plugins:

| v1 API | v2 Replacement |
|--------|----------------|
| `tauri::api::dialog` | `tauri-plugin-dialog` |
| `tauri::api::http` | `tauri-plugin-http` |
| `tauri::api::process` | `tauri-plugin-process` |
| `tauri::api::path` functions | `tauri::Manager::path` |

### BREAKING: Rust API Changes

#### Removed APIs

| v1 | v2 Alternative |
|----|----------------|
| `App::clipboard_manager` | `tauri-plugin-clipboard-manager` |
| `App::global_shortcut_manager` | `tauri-plugin-global-shortcut` |
| `App::get_cli_matches` | `tauri-plugin-cli` |
| `tauri::updater` | `tauri-plugin-updater` |

#### Renamed Types/Methods

| v1 | v2 |
|----|-----|
| `Window` | `WebviewWindow` |
| `Manager::get_window` | `Manager::get_webview_window` |

#### Menu API Changes

**Before:**
```rust
use tauri::{Menu, CustomMenuItem};
let menu = Menu::new()
    .add_item(CustomMenuItem::new("quit", "Quit"));
```

**After:**
```rust
use tauri::menu::{MenuBuilder, MenuItemBuilder};
let menu = MenuBuilder::new(app)
    .item(&MenuItemBuilder::with_id("quit", "Quit").build(app)?)
    .build()?;
```

#### Tray API Changes

**Before:**
```rust
use tauri::SystemTray;
SystemTray::new().with_menu(menu);
```

**After:**
```rust
use tauri::tray::TrayIconBuilder;
TrayIconBuilder::new()
    .menu(&menu)
    .on_menu_event(|app, event| { ... })
    .on_tray_icon_event(|tray, event| { ... })
    .build(app)?;
```

---

### BREAKING: JavaScript API Changes

#### Package Renames

| v1 | v2 |
|----|-----|
| `@tauri-apps/api/tauri` | `@tauri-apps/api/core` |
| `@tauri-apps/api/window` | `@tauri-apps/api/webviewWindow` |

#### Core API Reduction

The core `@tauri-apps/api` package now only includes:
- `core`
- `path`
- `event`
- `webviewWindow`

All other APIs require plugin packages.

---

### BREAKING: Plugin Migration

All formerly built-in APIs are now separate plugins:

| v1 Import | v2 Plugin Package |
|-----------|-------------------|
| `@tauri-apps/api/cli` | `@tauri-apps/plugin-cli` |
| `@tauri-apps/api/clipboard` | `@tauri-apps/plugin-clipboard-manager` |
| `@tauri-apps/api/dialog` | `@tauri-apps/plugin-dialog` |
| `@tauri-apps/api/fs` | `@tauri-apps/plugin-fs` |
| `@tauri-apps/api/global-shortcut` | `@tauri-apps/plugin-global-shortcut` |
| `@tauri-apps/api/http` | `@tauri-apps/plugin-http` |
| `@tauri-apps/api/notification` | `@tauri-apps/plugin-notification` |
| `@tauri-apps/api/os` | `@tauri-apps/plugin-os` |
| `@tauri-apps/api/process` | `@tauri-apps/plugin-process` |
| `@tauri-apps/api/shell` | `@tauri-apps/plugin-shell` |
| `@tauri-apps/api/updater` | `@tauri-apps/plugin-updater` |

#### Installing Plugins

```bash
# JavaScript
npm install @tauri-apps/plugin-fs

# Rust (add to Cargo.toml)
cargo add tauri-plugin-fs
```

Register plugins in your Rust code:

```rust
fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_fs::init())
        .run(tauri::generate_context!())
        .expect("error running app");
}
```

### BREAKING: File System Plugin Changes

Function renames in `@tauri-apps/plugin-fs`:

| v1 | v2 |
|----|-----|
| `createDir` | `mkdir` |
| `readBinaryFile` | `readFile` |
| `writeBinaryFile` | `writeFile` |
| `removeDir` | `remove` |
| `removeFile` | `remove` |
| `renameFile` | `rename` |
| `Dir` enum | `BaseDirectory` |

### BREAKING: Event System Changes

| v1 | v2 |
|----|-----|
| `emit()` | Broadcasts to ALL listeners (behavior change) |
| N/A | `emit_to()` - target specific event targets |
| `listen_global` | `listen_any` |

### BREAKING: Windows Origin URL

Production Windows apps now serve from `http://tauri.localhost` instead of `https://`.

**Impact:** IndexedDB and cookies will reset unless you preserve the old behavior:

```json
{
  "app": {
    "windows": [{
      "useHttpsScheme": true
    }]
  }
}
```

### BREAKING: Environment Variables

| v1 | v2 |
|----|-----|
| `TAURI_PRIVATE_KEY` | `TAURI_SIGNING_PRIVATE_KEY` |
| `TAURI_KEY_PASSWORD` | `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` |
| `TAURI_DEV_SERVER_PORT` | `TAURI_CLI_PORT` |
| Platform variables | Now prefixed `TAURI_ENV_` |

### Mobile Support Setup

To target mobile alongside desktop:

**1. Update Cargo.toml:**
```toml
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
```

**2. Rename src/main.rs to src/lib.rs:**
```rust
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error running app");
}
```

**3. Create new src/main.rs:**
```rust
fn main() {
    app_lib::run();
}
```

---

## V2 Beta to V2 Stable Migration

### BREAKING: Core Permission Prefix

All core permissions now require the `"core:"` prefix:

**Before (beta):**
```json
{
  "permissions": [
    "path:default",
    "event:default",
    "window:default"
  ]
}
```

**After (stable):**
```json
{
  "permissions": [
    "core:path:default",
    "core:event:default",
    "core:window:default"
  ]
}
```

**Simplified alternative:** Use `"core:default"` to include all default core permissions:

```json
{
  "permissions": ["core:default"]
}
```

---

### BREAKING: Mobile Dev Server Configuration

The mobile development server no longer exposes across networks. Traffic tunnels directly from local machine to devices.

**Before (beta):**
```javascript
const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM);
export default {
  server: {
    host: mobile ? '0.0.0.0' : false
  }
};
```

**After (stable):**
```javascript
const host = process.env.TAURI_DEV_HOST;
export default {
  server: {
    host: host || false
  }
};
```

Remove dependency on the `internal-ip` NPM package if previously used.

**iOS Device Development:** Requires additional steps. Use:
```bash
tauri ios dev --force-ip-prompt
```
Select the device's TUN address when prompted.

---

## Migration Checklist

### V1 to V2

- [ ] Run `npm run tauri migrate`
- [ ] Verify config structure changes (package -> top-level)
- [ ] Add `mainBinaryName` field
- [ ] Update bundle config structure
- [ ] Replace allowlist with capabilities
- [ ] Install required plugins
- [ ] Update Rust imports (Window -> WebviewWindow)
- [ ] Update JS imports (@tauri-apps/api/tauri -> core)
- [ ] Update FS function names if using fs plugin
- [ ] Update environment variable names
- [ ] Test event system behavior
- [ ] Verify Windows origin URL handling (IndexedDB/cookies)
- [ ] Update menu/tray code if used
- [ ] Remove deprecated Cargo features

### V2 Beta to V2 Stable

- [ ] Run `npm run tauri migrate`
- [ ] Add `core:` prefix to permission identifiers (or use `core:default`)
- [ ] Update mobile dev server configuration
- [ ] Remove `internal-ip` package dependency if present
- [ ] Test iOS device development with `--force-ip-prompt`

---

## Common Issues

| Issue | Solution |
|-------|----------|
| Permission denied errors | Check `src-tauri/capabilities/` files for required permissions |
| IndexedDB/localStorage lost (Windows) | Set `useHttpsScheme: true` in window config |
| Plugin not found | Add to Cargo.toml, register with `.plugin()`, install npm package |
| Mobile build fails | Verify `[lib]` section in Cargo.toml and `src/lib.rs` with mobile entry point |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.