migrating-tauri-apps
npx skills add https://github.com/beshkenadze/claude-code-tauri-skills --skill migrating-tauri-apps
Agent 安装分布
Skill 文档
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:
# 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 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:
{
"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-clientreqwest-native-tls-vendoredprocess-command-apishell-open-apiwindows7-compatupdatersystem-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:
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
| 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:
corepatheventwebviewWindow
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
# 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:
| 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:
{
"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:
[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
mainBinaryNamefield - 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 usecore:default) - Update mobile dev server configuration
- Remove
internal-ippackage 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 |