mcpField
M
migrating-tauri-apps

migrating-tauri-apps

github.com/dchukDevelopment36142 installsUpdated 40w ago
Repository

About migrating-tauri-apps

A migration skill for developers moving Tauri applications from v1 or v2 beta to v2 stable. It combines CLI-assisted migration guidance with a checklist of configuration, API, plugin, and platform changes that still need review.

Key features

  1. 01CLI-assisted migration workflow
  2. 02Configuration and capability changes
  3. 03Rust and JavaScript API updates
  4. 04Plugin and environment variable changes
  5. 05Migration checklist and issue guidance

Use cases

  1. 01Planning a Tauri v1 to v2 upgrade
  2. 02Updating a v2 beta app to stable
  3. 03Reviewing migration changes after the CLI runs

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill migrating-tauri-apps

After installing, type/migrating-tauri-appsin Claude Code to confirm it loaded.

Details

From the project README

Tauri Migration Guide

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

Migration Paths

Source VersionTargetComplexity
Tauri v1.xv2 stableHigh - significant breaking changes
Tauri v2 betav2 stableLow - minor breaking changes

Automated Migration

Both migration paths support automated migration via the Tauri CLI:

# 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):

{
  "package": {
    "productName": "my-app",
    "version": "1.0.0"
  },
  "tauri": {
    "bundle": { ... },
    "allowlist": { ... }
  }
}

After (v2):

{
  "productName": "my-app",
  "version": "1.0.0",
  "mainBinaryName": "my-app",
  "identifier": "com.example.myapp",
  "app": { ... },
  "bundle": { ... }
}
Key Renames
v1 Pathv2 Path
package.productNameproductName (top-level)
package.versionversion (top-level)
tauriapp
tauri.bundlebundle (top-level)
tauri.bundle.identifieridentifier (top-level)
tauri.systemTrayapp.trayIcon
build.distDirfrontendDist
build.devPathdevUrl
BREAKING: New Required Field

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

{
  "productName": "My App",
  "mainBinaryName": "My App"
}
Bundle Configuration Reorganization

Platform-specific bundle configs moved under their platform key:

Before:

{
  "tauri": {
    "bundle": {
      "dmg": { ... },
      "deb": { ... }
    }
  }
}

After:

{
  "bundle": {
    "macOS": {
      "dmg": { ... }
    },
    "linux": {
      "deb": { ... }
    }
  }
}
Updater Configuration

If using the app updater, add to bundle config:

{
  "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:

{
  "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 APIv2 Replacement
tauri::api::dialogtauri-plugin-dialog
tauri::api::httptauri-plugin-http
tauri::api::processtauri-plugin-process
tauri::api::path functionstauri::Manager::path
BREAKING: Rust API Changes
Removed APIs
v1v2 Alternative
App::clipboard_managertauri-plugin-clipboard-manager
App::global_shortcut_managertauri-plugin-global-shortcut
App::get_cli_matchestauri-plugin-cli
tauri::updatertauri-plugin-updater
Renamed Types/Methods
v1v2
WindowWebviewWindow
Manager::get_windowManager::get_webview_window
Menu API Changes

Before:

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

After:

use tauri::menu::{MenuBuilder, MenuItemBuilder};
let menu = MenuBuilder::new(app)
    .item(&MenuItemBuilder::with_id("quit", "Quit").build(app)?)
    .build()?;
Tray API Changes

Before:

use tauri::SystemTray;
SystemTray::new().with_menu(menu);

After:

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
v1v2
@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 Importv2 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
# JavaScript
npm install @tauri-apps/plugin-fs

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

Register plugins in your Rust code:

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:

v1v2
createDirmkdir
readBinaryFilereadFile
writeBinaryFilewriteFile
removeDirremove
removeFileremove
renameFilerename
Dir enumBaseDirectory
BREAKING: Event System Changes
v1v2
emit()Broadcasts to ALL listeners (behavior change)
N/Aemit_to() - target specific event targets
listen_globallisten_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:

{
  "app": {
    "windows": [{
      "useHttpsScheme": true
    }]
  }
}
BREAKING: Environment Variables
v1v2
TAURI_PRIVATE_KEYTAURI_SIGNING_PRIVATE_KEY
TAURI_KEY_PASSWORDTAURI_SIGNING_PRIVATE_KEY_PASSWORD
TAURI_DEV_SERVER_PORTTAURI_CLI_PORT
Platform variablesNow prefixed TAURI_ENV_
Mobile Support Setup

To target mobile alongside desktop:

1. Update Cargo.toml:

[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

2. Rename src/main.rs to src/lib.rs:

#[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:

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):

{
  "permissions": [
    "path:default",
    "event:default",
    "window:default"
  ]
}

After (stable):

{
  "permissions": [
    "core:path:default",
    "core:event:default",
    "core:window:default"
  ]
}

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

{
  "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):

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

After (stable):

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:

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

IssueSolution
Permission denied errorsCheck src-tauri/capabilities/ files for required permissions
IndexedDB/localStorage lost (Windows)Set useHttpsScheme: true in window config
Plugin not foundAdd to Cargo.toml, register with .plugin(), install npm package
Mobile build failsVerify [lib] section in Cargo.toml and src/lib.rs with mobile entry point

Comments

Markdown supported