packwise-skills 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursorrules +23 -23
- package/CLAUDE.md +25 -25
- package/LICENSE +21 -0
- package/README.md +404 -295
- package/audit.md +224 -224
- package/bin/packwise.js +322 -155
- package/install.sh +123 -0
- package/package.json +32 -31
- package/skill.md +944 -719
- package/sub-skills/ai/local-llm.md +183 -183
- package/sub-skills/ai/python-ml.md +164 -164
- package/sub-skills/backend/go-server.md +184 -184
- package/sub-skills/backend/java-spring.md +241 -241
- package/sub-skills/backend/node-server.md +164 -164
- package/sub-skills/backend/php-laravel.md +175 -175
- package/sub-skills/backend/python-server.md +164 -164
- package/sub-skills/backend/rust-backend.md +118 -118
- package/sub-skills/cli/python-cli.md +236 -236
- package/sub-skills/cli/sdk-library.md +497 -497
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -350
- package/sub-skills/cloud/docker.md +191 -191
- package/sub-skills/cloud/kubernetes.md +277 -277
- package/sub-skills/cloud/payment-integration.md +307 -307
- package/sub-skills/cross-platform/multiplatform.md +252 -252
- package/sub-skills/desktop/electron.md +783 -783
- package/sub-skills/desktop/game-dev.md +443 -443
- package/sub-skills/desktop/native-app.md +123 -123
- package/sub-skills/desktop/scenarios.md +443 -443
- package/sub-skills/desktop/smart-platforms.md +324 -324
- package/sub-skills/desktop/tauri.md +428 -428
- package/sub-skills/desktop/vr-ar.md +252 -252
- package/sub-skills/desktop/web-to-desktop.md +153 -153
- package/sub-skills/embedded/car-infotainment.md +129 -129
- package/sub-skills/embedded/esp32.md +184 -184
- package/sub-skills/embedded/ros.md +150 -150
- package/sub-skills/embedded/stm32.md +160 -160
- package/sub-skills/mobile/android.md +322 -322
- package/sub-skills/mobile/capacitor.md +232 -232
- package/sub-skills/mobile/flutter-mobile.md +138 -138
- package/sub-skills/mobile/harmonyos.md +150 -150
- package/sub-skills/mobile/ios.md +245 -245
- package/sub-skills/mobile/react-native.md +443 -443
- package/sub-skills/mobile/wearables.md +230 -230
- package/sub-skills/plugins/browser-extension.md +308 -308
- package/sub-skills/plugins/jetbrains-plugin.md +226 -226
- package/sub-skills/plugins/vscode-extension.md +204 -204
- package/sub-skills/security/security-tools.md +174 -174
- package/sub-skills/web/monorepo.md +274 -274
- package/sub-skills/web/pwa.md +220 -220
- package/sub-skills/web/serverless-edge.md +295 -295
- package/sub-skills/web/spa.md +266 -266
- package/sub-skills/web/ssr.md +228 -228
- package/sub-skills/web/wasm.md +243 -243
|
@@ -1,428 +1,428 @@
|
|
|
1
|
-
# Tauri 2.x Build Sub-Skill
|
|
2
|
-
|
|
3
|
-
Rust backend + system WebView. Minimal footprint (2–6MB). Suitable for L1–L3 complexity projects.
|
|
4
|
-
|
|
5
|
-
**Current version**: Tauri 2.11.x / Tauri CLI 2.11.x (2025-2026)
|
|
6
|
-
|
|
7
|
-
> ⚠️ **Breaking changes since Tauri 2.2**: v2.10 renamed signer env vars (`TAURI_PRIVATE_KEY` → `TAURI_SIGNING_PRIVATE_KEY`). v2.8 raised iOS deployment target to 14.0. v2.5 removed `WebviewAttributes` re-export. v2.3 deprecated `Manager::unmanage`. Auto-updater plugin v2.5 removed `UpdaterBuilder::new` (use `UpdaterExt::updater_builder`). See [tauri.app/start/migrate/from-tauri-2-0](https://v2.tauri.app/start/migrate/from-tauri-2-0/).
|
|
8
|
-
|
|
9
|
-
## When to Use
|
|
10
|
-
|
|
11
|
-
- Frontend uses React/Vue/Svelte/Solid/Vanilla JS
|
|
12
|
-
- Backend can be rewritten in Rust
|
|
13
|
-
- Minimal package size required (2–6MB vs Electron's 80–120MB)
|
|
14
|
-
- Mobile support needed (iOS/Android — stable since Tauri 2.0)
|
|
15
|
-
- Strong sandboxing required (default permission model)
|
|
16
|
-
|
|
17
|
-
## Key Features
|
|
18
|
-
|
|
19
|
-
- **Mobile support** (iOS/Android) — stable and production-ready since Tauri 2.0
|
|
20
|
-
- **Capabilities/Permissions system** — fine-grained, JSON-based permission model (CRITICAL for security)
|
|
21
|
-
- **Plugin ecosystem**: tauri-plugin-shell, tauri-plugin-fs, tauri-plugin-http, tauri-plugin-notification, tauri-plugin-store, tauri-plugin-sql, tauri-plugin-log
|
|
22
|
-
- **Type-safe IPC** — auto-generated TypeScript bindings from Rust (`invoke` API)
|
|
23
|
-
- **Built-in auto-updater** — differential updates, GitHub/custom server support
|
|
24
|
-
- **NSIS installer** on Windows, AppImage/DEB/RPM on Linux, DMG on macOS
|
|
25
|
-
|
|
26
|
-
## Comparison with Electron
|
|
27
|
-
|
|
28
|
-
| Feature | Electron 43.x | Tauri 2.11.x |
|
|
29
|
-
|---------|--------------|-------------|
|
|
30
|
-
| Size | 80–120MB | 2–6MB |
|
|
31
|
-
| Backend | Node.js | Rust |
|
|
32
|
-
| Browser engine | Bundled Chromium | System WebView |
|
|
33
|
-
| Native modules | Full support | Rust crates |
|
|
34
|
-
| Learning curve | Low | Medium-High (Rust) |
|
|
35
|
-
| Mobile | No | Yes (iOS/Android) |
|
|
36
|
-
| Security | Manual config | Sandboxed by default (capabilities) |
|
|
37
|
-
| WebView2 (Windows) | Bundled | Required (pre-installed Win10 21H2+, Win11) |
|
|
38
|
-
|
|
39
|
-
## Prerequisites
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Rust toolchain
|
|
43
|
-
curl --proto '=https' --tlsv11.2 -sSf https://sh.rustup.rs | sh
|
|
44
|
-
|
|
45
|
-
# Tauri CLI
|
|
46
|
-
cargo install tauri-cli
|
|
47
|
-
|
|
48
|
-
# Platform dependencies
|
|
49
|
-
# Windows: WebView2 (pre-installed on Win10 21H2+), Visual Studio Build Tools
|
|
50
|
-
# macOS: Xcode Command Line Tools
|
|
51
|
-
# Linux: libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev
|
|
52
|
-
|
|
53
|
-
# Node.js 20+ (for frontend)
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Project Creation
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
# Recommended: create with frontend framework
|
|
60
|
-
npm create tauri-app@latest my-app -- --template react-ts
|
|
61
|
-
# Templates available: react-ts, vue-ts, svelte-ts, solid-ts, vanilla-ts
|
|
62
|
-
|
|
63
|
-
cd my-app
|
|
64
|
-
npm install
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Core Configuration (tauri.conf.json)
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"productName": "MyApp",
|
|
72
|
-
"version": "1.0.0",
|
|
73
|
-
"identifier": "com.example.myapp",
|
|
74
|
-
"build": {
|
|
75
|
-
"frontendDist": "../dist",
|
|
76
|
-
"devUrl": "http://localhost:5173",
|
|
77
|
-
"beforeDevCommand": "npm run dev",
|
|
78
|
-
"beforeBuildCommand": "npm run build"
|
|
79
|
-
},
|
|
80
|
-
"app": {
|
|
81
|
-
"windows": [
|
|
82
|
-
{
|
|
83
|
-
"title": "MyApp",
|
|
84
|
-
"width": 1200,
|
|
85
|
-
"height": 800,
|
|
86
|
-
"resizable": true,
|
|
87
|
-
"fullscreen": false
|
|
88
|
-
}
|
|
89
|
-
],
|
|
90
|
-
"security": {
|
|
91
|
-
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com"
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
"bundle": {
|
|
95
|
-
"active": true,
|
|
96
|
-
"targets": "all",
|
|
97
|
-
"icon": [
|
|
98
|
-
"icons/32x32.png",
|
|
99
|
-
"icons/128x128.png",
|
|
100
|
-
"icons/128x128@2x.png",
|
|
101
|
-
"icons/icon.ico",
|
|
102
|
-
"icons/icon.icns"
|
|
103
|
-
],
|
|
104
|
-
"windows": {
|
|
105
|
-
"nsis": {
|
|
106
|
-
"installMode": "both"
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
"macOS": {
|
|
110
|
-
"minimumSystemVersion": "10.15"
|
|
111
|
-
},
|
|
112
|
-
"linux": {
|
|
113
|
-
"deb": {
|
|
114
|
-
"depends": ["libwebkit2gtk-4.1-0"]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
"plugins": {
|
|
119
|
-
"shell": {
|
|
120
|
-
"open": true
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Capabilities & Permissions (CRITICAL — Tauri 2.x Security Model)
|
|
127
|
-
|
|
128
|
-
Tauri 2.x uses a **capabilities/permissions** system. Without proper configuration, your app cannot access ANY native functionality.
|
|
129
|
-
|
|
130
|
-
```text
|
|
131
|
-
src-tauri/
|
|
132
|
-
├── capabilities/
|
|
133
|
-
│ └── default.json ← Permission declarations
|
|
134
|
-
├── tauri.conf.json
|
|
135
|
-
├── Cargo.toml
|
|
136
|
-
├── build.rs ← REQUIRED: `fn main() { tauri_build::build() }`
|
|
137
|
-
└── src/
|
|
138
|
-
├── main.rs ← Desktop entry point
|
|
139
|
-
└── lib.rs ← Shared logic (mobile + desktop)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
// src-tauri/capabilities/default.json
|
|
144
|
-
{
|
|
145
|
-
"$schema": "../gen/schemas/desktop-schema.json",
|
|
146
|
-
"identifier": "default",
|
|
147
|
-
"description": "Default capabilities for the main window",
|
|
148
|
-
"windows": ["main"],
|
|
149
|
-
"permissions": [
|
|
150
|
-
"core:default",
|
|
151
|
-
"shell:allow-open",
|
|
152
|
-
"fs:allow-read",
|
|
153
|
-
"fs:allow-write",
|
|
154
|
-
"fs:allow-exists",
|
|
155
|
-
"dialog:allow-open",
|
|
156
|
-
"dialog:allow-save",
|
|
157
|
-
"notification:default",
|
|
158
|
-
"store:default",
|
|
159
|
-
"http:default",
|
|
160
|
-
"clipboard-manager:allow-read-text",
|
|
161
|
-
"clipboard-manager:allow-write-text"
|
|
162
|
-
]
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
**Common Mistake**: Forgetting to declare permissions. The app builds and runs in dev but crashes in production with "permission denied" errors.
|
|
167
|
-
|
|
168
|
-
**Common Mistake**: Using `"core:default"` without understanding what it includes. Check `src-tauri/gen/schemas/` for the full permission list.
|
|
169
|
-
|
|
170
|
-
## Rust Backend Example (Correct Data Path)
|
|
171
|
-
|
|
172
|
-
**Required: `src-tauri/build.rs`** — Tauri will NOT compile without this file:
|
|
173
|
-
|
|
174
|
-
```rust
|
|
175
|
-
// src-tauri/build.rs
|
|
176
|
-
fn main() {
|
|
177
|
-
tauri_build::build()
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**Required: `[build-dependencies]` in `Cargo.toml`:**
|
|
182
|
-
|
|
183
|
-
```toml
|
|
184
|
-
[build-dependencies]
|
|
185
|
-
tauri-build = { version = "2", features = [] }
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
```rust
|
|
189
|
-
use rusqlite::Connection;
|
|
190
|
-
use tauri::Manager;
|
|
191
|
-
use std::sync::Mutex;
|
|
192
|
-
|
|
193
|
-
struct AppState {
|
|
194
|
-
db: Mutex<Connection>,
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
#[tauri::command]
|
|
198
|
-
fn get_messages(state: tauri::State<AppState>) -> Result<Vec<String>, String> {
|
|
199
|
-
let conn = state.db.lock().map_err(|e| e.to_string())?;
|
|
200
|
-
// Query database...
|
|
201
|
-
Ok(vec![])
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
pub fn run() {
|
|
205
|
-
tauri::Builder::default()
|
|
206
|
-
.setup(|app| {
|
|
207
|
-
// CORRECT: Use app_data_dir for persistent data (NOT relative path)
|
|
208
|
-
let app_data = app.path().app_data_dir()
|
|
209
|
-
.expect("Failed to get app data dir");
|
|
210
|
-
std::fs::create_dir_all(&app_data).ok();
|
|
211
|
-
let db_path = app_data.join("data.db");
|
|
212
|
-
let conn = Connection::open(&db_path)
|
|
213
|
-
.expect("Failed to open database");
|
|
214
|
-
|
|
215
|
-
app.manage(AppState {
|
|
216
|
-
db: Mutex::new(conn),
|
|
217
|
-
});
|
|
218
|
-
Ok(())
|
|
219
|
-
})
|
|
220
|
-
.invoke_handler(tauri::generate_handler![get_messages])
|
|
221
|
-
.run(tauri::generate_context!())
|
|
222
|
-
.expect("error while running tauri application");
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Frontend call:**
|
|
227
|
-
```typescript
|
|
228
|
-
import { invoke } from '@tauri-apps/api/core';
|
|
229
|
-
const messages = await invoke<string[]>('get_messages');
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Build Commands
|
|
233
|
-
|
|
234
|
-
```bash
|
|
235
|
-
# Desktop
|
|
236
|
-
cargo tauri build # Default platform
|
|
237
|
-
cargo tauri build --target x86_64-pc-windows-msvc # Windows x64
|
|
238
|
-
cargo tauri build --target aarch64-pc-windows-msvc # Windows ARM64
|
|
239
|
-
cargo tauri build --target aarch64-apple-darwin # macOS ARM64 (Apple Silicon)
|
|
240
|
-
cargo tauri build --target x86_64-apple-darwin # macOS x64 (Intel)
|
|
241
|
-
cargo tauri build --target universal-apple-darwin # macOS Universal Binary
|
|
242
|
-
cargo tauri build --target x86_64-unknown-linux-gnu # Linux x64
|
|
243
|
-
cargo tauri build --target aarch64-unknown-linux-gnu # Linux ARM64
|
|
244
|
-
|
|
245
|
-
# Mobile
|
|
246
|
-
cargo tauri android init # Initialize Android project (first time)
|
|
247
|
-
cargo tauri android build # Build Android APK/AAB
|
|
248
|
-
cargo tauri ios init # Initialize iOS project (first time, macOS only)
|
|
249
|
-
cargo tauri ios build # Build iOS IPA (macOS only)
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Mobile Build (iOS/Android)
|
|
253
|
-
|
|
254
|
-
### Android
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
# Prerequisites: Android Studio, JDK 17, Android SDK 34+
|
|
258
|
-
cargo tauri android init
|
|
259
|
-
cargo tauri android build --target aarch64 # ARM64
|
|
260
|
-
cargo tauri android build --target arm # ARMv7
|
|
261
|
-
cargo tauri android build --target x86_64 # x86_64 (emulator)
|
|
262
|
-
|
|
263
|
-
# Output: src-tauri/gen/android/app/build/outputs/
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### iOS
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
# Prerequisites: macOS + Xcode 15+ + Apple Developer account
|
|
270
|
-
cargo tauri ios init
|
|
271
|
-
cargo tauri ios build
|
|
272
|
-
|
|
273
|
-
# Output: src-tauri/gen/apple/build/
|
|
274
|
-
# Open in Xcode for signing and distribution
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Google Play Distribution
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
# Build AAB (Android App Bundle — required by Play Store)
|
|
281
|
-
cargo tauri android build --aab
|
|
282
|
-
# Output: gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab
|
|
283
|
-
|
|
284
|
-
# Build APK (for direct distribution/testing)
|
|
285
|
-
cargo tauri android build --apk
|
|
286
|
-
|
|
287
|
-
# Per-architecture APKs (smaller, for testing outside Play Store)
|
|
288
|
-
cargo tauri android build --apk --split-per-abi
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### iOS App Store Distribution
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
# Build and open Xcode for archiving
|
|
295
|
-
cargo tauri ios build --open
|
|
296
|
-
|
|
297
|
-
# In Xcode: Product → Archive → Distribute → App Store Connect
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### Physical iOS Device Development
|
|
301
|
-
|
|
302
|
-
```bash
|
|
303
|
-
# Physical device requires dev server on local network
|
|
304
|
-
# 1. Connect device via Xcode → Window → Devices and Simulators
|
|
305
|
-
# 2. Run with forced IP prompt
|
|
306
|
-
cargo tauri ios dev --force-ip-prompt
|
|
307
|
-
|
|
308
|
-
# 3. Configure Vite to use TAURI_DEV_HOST:
|
|
309
|
-
# vite.config.js:
|
|
310
|
-
# const host = process.env.TAURI_DEV_HOST;
|
|
311
|
-
# server: { host: host || false, port: 1420 }
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Android Environment Variables (Required)
|
|
315
|
-
|
|
316
|
-
```bash
|
|
317
|
-
# JAVA_HOME — Android Studio's bundled JBR
|
|
318
|
-
# Linux: /opt/android-studio/jbr
|
|
319
|
-
# macOS: /Applications/Android Studio.app/Contents/jbr/Contents/Home
|
|
320
|
-
# Windows: C:\Program Files\Android\Android Studio\jbr
|
|
321
|
-
|
|
322
|
-
# ANDROID_HOME
|
|
323
|
-
# Linux/macOS: $HOME/Android/Sdk
|
|
324
|
-
# Windows: %LocalAppData%\Android\Sdk
|
|
325
|
-
|
|
326
|
-
# Rust targets for Android
|
|
327
|
-
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
|
|
328
|
-
|
|
329
|
-
# Rust targets for iOS
|
|
330
|
-
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## Auto-Update
|
|
334
|
-
|
|
335
|
-
```json
|
|
336
|
-
// tauri.conf.json
|
|
337
|
-
{
|
|
338
|
-
"plugins": {
|
|
339
|
-
"updater": {
|
|
340
|
-
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIH...",
|
|
341
|
-
"endpoints": [
|
|
342
|
-
"https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}"
|
|
343
|
-
]
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
```rust
|
|
350
|
-
// src-tauri/src/lib.rs
|
|
351
|
-
// ⚠️ Tauri 2.5+: UpdaterBuilder::new removed, use UpdaterExt::updater_builder
|
|
352
|
-
use tauri_plugin_updater::UpdaterExt;
|
|
353
|
-
|
|
354
|
-
fn main() {
|
|
355
|
-
tauri::Builder::default()
|
|
356
|
-
.plugin(tauri_plugin_updater::Builder::new().build())
|
|
357
|
-
.setup(|app| {
|
|
358
|
-
let handle = app.handle().clone();
|
|
359
|
-
tauri::async_runtime::spawn(async move {
|
|
360
|
-
let update = handle.updater().check().await;
|
|
361
|
-
// Handle update notification
|
|
362
|
-
});
|
|
363
|
-
Ok(())
|
|
364
|
-
})
|
|
365
|
-
.run(tauri::generate_context!())
|
|
366
|
-
.expect("error");
|
|
367
|
-
}
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
## Code Signing
|
|
371
|
-
|
|
372
|
-
### Windows
|
|
373
|
-
|
|
374
|
-
```bash
|
|
375
|
-
# Sign the .msi or .exe after build
|
|
376
|
-
signtool sign /f certificate.pfx /p password /tr http://timestamp.digicert.com /td sha256 src-tauri/target/release/bundle/msi/*.msi
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### Auto-Update Signing (Tauri 2.10+)
|
|
380
|
-
|
|
381
|
-
```bash
|
|
382
|
-
# ⚠️ Environment variables RENAMED in Tauri 2.10:
|
|
383
|
-
# OLD: TAURI_PRIVATE_KEY, TAURI_PRIVATE_KEY_PATH, TAURI_PRIVATE_KEY_PASSWORD
|
|
384
|
-
# NEW: TAURI_SIGNING_PRIVATE_KEY, TAURI_SIGNING_PRIVATE_KEY_PATH, TAURI_SIGNING_PRIVATE_KEY_PASSWORD
|
|
385
|
-
export TAURI_SIGNING_PRIVATE_KEY="dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIH..."
|
|
386
|
-
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### macOS
|
|
390
|
-
|
|
391
|
-
```json
|
|
392
|
-
// tauri.conf.json
|
|
393
|
-
{
|
|
394
|
-
"bundle": {
|
|
395
|
-
"macOS": {
|
|
396
|
-
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)",
|
|
397
|
-
"entitlements": "entitlements.plist"
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
```bash
|
|
404
|
-
# Notarize after build
|
|
405
|
-
xcrun notarytool submit src-tauri/target/release/bundle/dmg/*.dmg \
|
|
406
|
-
--apple-id your@email.com \
|
|
407
|
-
--password app-specific-password \
|
|
408
|
-
--team-id TEAM_ID \
|
|
409
|
-
--wait
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## Common Pitfalls
|
|
413
|
-
|
|
414
|
-
| Issue | Fix |
|
|
415
|
-
|-------|-----|
|
|
416
|
-
| Windows missing WebView2 | Pre-installed on Win10 21H2+. For older: download from developer.microsoft.com |
|
|
417
|
-
| Linux compile failure | `sudo apt install libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev` |
|
|
418
|
-
| macOS notarization | Requires Apple Developer ID ($99/year) + notarytool |
|
|
419
|
-
| Slow Rust compilation | First build 5–15 min; use `cargo tauri build --debug` for faster dev builds |
|
|
420
|
-
| SPA route 404 on reload | Configure `app.security.csp` in tauri.conf.json; use hash-based routing |
|
|
421
|
-
| Permission denied in production | Declare capabilities in `src-tauri/capabilities/default.json` |
|
|
422
|
-
| Database path wrong | Use `app.path().app_data_dir()` not relative paths |
|
|
423
|
-
| Mobile build fails | Run `cargo tauri android/ios init` first; check SDK/NDK paths |
|
|
424
|
-
| Auto-update not working | Ensure `pubkey` matches signing key; check endpoint URL format; env vars renamed in v2.10 (see above) |
|
|
425
|
-
| `invoke` returns undefined | Check Rust command name matches `tauri::generate_handler![]` |
|
|
426
|
-
| WebView2 crash on old Windows | Set `"windows": {"webviewInstallMode": {"type": "embedBootstrapper"}}` in tauri.conf.json |
|
|
427
|
-
| Signer env vars not working | Tauri 2.10+ renamed: `TAURI_SIGNING_PRIVATE_KEY` (was `TAURI_PRIVATE_KEY`) |
|
|
428
|
-
| `WebviewAttributes` import fails | Removed from `tauri` crate in v2.5; import from `tauri::webview::WebviewAttributes` instead |
|
|
1
|
+
# Tauri 2.x Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Rust backend + system WebView. Minimal footprint (2–6MB). Suitable for L1–L3 complexity projects.
|
|
4
|
+
|
|
5
|
+
**Current version**: Tauri 2.11.x / Tauri CLI 2.11.x (2025-2026)
|
|
6
|
+
|
|
7
|
+
> ⚠️ **Breaking changes since Tauri 2.2**: v2.10 renamed signer env vars (`TAURI_PRIVATE_KEY` → `TAURI_SIGNING_PRIVATE_KEY`). v2.8 raised iOS deployment target to 14.0. v2.5 removed `WebviewAttributes` re-export. v2.3 deprecated `Manager::unmanage`. Auto-updater plugin v2.5 removed `UpdaterBuilder::new` (use `UpdaterExt::updater_builder`). See [tauri.app/start/migrate/from-tauri-2-0](https://v2.tauri.app/start/migrate/from-tauri-2-0/).
|
|
8
|
+
|
|
9
|
+
## When to Use
|
|
10
|
+
|
|
11
|
+
- Frontend uses React/Vue/Svelte/Solid/Vanilla JS
|
|
12
|
+
- Backend can be rewritten in Rust
|
|
13
|
+
- Minimal package size required (2–6MB vs Electron's 80–120MB)
|
|
14
|
+
- Mobile support needed (iOS/Android — stable since Tauri 2.0)
|
|
15
|
+
- Strong sandboxing required (default permission model)
|
|
16
|
+
|
|
17
|
+
## Key Features
|
|
18
|
+
|
|
19
|
+
- **Mobile support** (iOS/Android) — stable and production-ready since Tauri 2.0
|
|
20
|
+
- **Capabilities/Permissions system** — fine-grained, JSON-based permission model (CRITICAL for security)
|
|
21
|
+
- **Plugin ecosystem**: tauri-plugin-shell, tauri-plugin-fs, tauri-plugin-http, tauri-plugin-notification, tauri-plugin-store, tauri-plugin-sql, tauri-plugin-log
|
|
22
|
+
- **Type-safe IPC** — auto-generated TypeScript bindings from Rust (`invoke` API)
|
|
23
|
+
- **Built-in auto-updater** — differential updates, GitHub/custom server support
|
|
24
|
+
- **NSIS installer** on Windows, AppImage/DEB/RPM on Linux, DMG on macOS
|
|
25
|
+
|
|
26
|
+
## Comparison with Electron
|
|
27
|
+
|
|
28
|
+
| Feature | Electron 43.x | Tauri 2.11.x |
|
|
29
|
+
|---------|--------------|-------------|
|
|
30
|
+
| Size | 80–120MB | 2–6MB |
|
|
31
|
+
| Backend | Node.js | Rust |
|
|
32
|
+
| Browser engine | Bundled Chromium | System WebView |
|
|
33
|
+
| Native modules | Full support | Rust crates |
|
|
34
|
+
| Learning curve | Low | Medium-High (Rust) |
|
|
35
|
+
| Mobile | No | Yes (iOS/Android) |
|
|
36
|
+
| Security | Manual config | Sandboxed by default (capabilities) |
|
|
37
|
+
| WebView2 (Windows) | Bundled | Required (pre-installed Win10 21H2+, Win11) |
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Rust toolchain
|
|
43
|
+
curl --proto '=https' --tlsv11.2 -sSf https://sh.rustup.rs | sh
|
|
44
|
+
|
|
45
|
+
# Tauri CLI
|
|
46
|
+
cargo install tauri-cli
|
|
47
|
+
|
|
48
|
+
# Platform dependencies
|
|
49
|
+
# Windows: WebView2 (pre-installed on Win10 21H2+), Visual Studio Build Tools
|
|
50
|
+
# macOS: Xcode Command Line Tools
|
|
51
|
+
# Linux: libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev
|
|
52
|
+
|
|
53
|
+
# Node.js 20+ (for frontend)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Project Creation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Recommended: create with frontend framework
|
|
60
|
+
npm create tauri-app@latest my-app -- --template react-ts
|
|
61
|
+
# Templates available: react-ts, vue-ts, svelte-ts, solid-ts, vanilla-ts
|
|
62
|
+
|
|
63
|
+
cd my-app
|
|
64
|
+
npm install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Core Configuration (tauri.conf.json)
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"productName": "MyApp",
|
|
72
|
+
"version": "1.0.0",
|
|
73
|
+
"identifier": "com.example.myapp",
|
|
74
|
+
"build": {
|
|
75
|
+
"frontendDist": "../dist",
|
|
76
|
+
"devUrl": "http://localhost:5173",
|
|
77
|
+
"beforeDevCommand": "npm run dev",
|
|
78
|
+
"beforeBuildCommand": "npm run build"
|
|
79
|
+
},
|
|
80
|
+
"app": {
|
|
81
|
+
"windows": [
|
|
82
|
+
{
|
|
83
|
+
"title": "MyApp",
|
|
84
|
+
"width": 1200,
|
|
85
|
+
"height": 800,
|
|
86
|
+
"resizable": true,
|
|
87
|
+
"fullscreen": false
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"security": {
|
|
91
|
+
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"bundle": {
|
|
95
|
+
"active": true,
|
|
96
|
+
"targets": "all",
|
|
97
|
+
"icon": [
|
|
98
|
+
"icons/32x32.png",
|
|
99
|
+
"icons/128x128.png",
|
|
100
|
+
"icons/128x128@2x.png",
|
|
101
|
+
"icons/icon.ico",
|
|
102
|
+
"icons/icon.icns"
|
|
103
|
+
],
|
|
104
|
+
"windows": {
|
|
105
|
+
"nsis": {
|
|
106
|
+
"installMode": "both"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"macOS": {
|
|
110
|
+
"minimumSystemVersion": "10.15"
|
|
111
|
+
},
|
|
112
|
+
"linux": {
|
|
113
|
+
"deb": {
|
|
114
|
+
"depends": ["libwebkit2gtk-4.1-0"]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"plugins": {
|
|
119
|
+
"shell": {
|
|
120
|
+
"open": true
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Capabilities & Permissions (CRITICAL — Tauri 2.x Security Model)
|
|
127
|
+
|
|
128
|
+
Tauri 2.x uses a **capabilities/permissions** system. Without proper configuration, your app cannot access ANY native functionality.
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
src-tauri/
|
|
132
|
+
├── capabilities/
|
|
133
|
+
│ └── default.json ← Permission declarations
|
|
134
|
+
├── tauri.conf.json
|
|
135
|
+
├── Cargo.toml
|
|
136
|
+
├── build.rs ← REQUIRED: `fn main() { tauri_build::build() }`
|
|
137
|
+
└── src/
|
|
138
|
+
├── main.rs ← Desktop entry point
|
|
139
|
+
└── lib.rs ← Shared logic (mobile + desktop)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
// src-tauri/capabilities/default.json
|
|
144
|
+
{
|
|
145
|
+
"$schema": "../gen/schemas/desktop-schema.json",
|
|
146
|
+
"identifier": "default",
|
|
147
|
+
"description": "Default capabilities for the main window",
|
|
148
|
+
"windows": ["main"],
|
|
149
|
+
"permissions": [
|
|
150
|
+
"core:default",
|
|
151
|
+
"shell:allow-open",
|
|
152
|
+
"fs:allow-read",
|
|
153
|
+
"fs:allow-write",
|
|
154
|
+
"fs:allow-exists",
|
|
155
|
+
"dialog:allow-open",
|
|
156
|
+
"dialog:allow-save",
|
|
157
|
+
"notification:default",
|
|
158
|
+
"store:default",
|
|
159
|
+
"http:default",
|
|
160
|
+
"clipboard-manager:allow-read-text",
|
|
161
|
+
"clipboard-manager:allow-write-text"
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Common Mistake**: Forgetting to declare permissions. The app builds and runs in dev but crashes in production with "permission denied" errors.
|
|
167
|
+
|
|
168
|
+
**Common Mistake**: Using `"core:default"` without understanding what it includes. Check `src-tauri/gen/schemas/` for the full permission list.
|
|
169
|
+
|
|
170
|
+
## Rust Backend Example (Correct Data Path)
|
|
171
|
+
|
|
172
|
+
**Required: `src-tauri/build.rs`** — Tauri will NOT compile without this file:
|
|
173
|
+
|
|
174
|
+
```rust
|
|
175
|
+
// src-tauri/build.rs
|
|
176
|
+
fn main() {
|
|
177
|
+
tauri_build::build()
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Required: `[build-dependencies]` in `Cargo.toml`:**
|
|
182
|
+
|
|
183
|
+
```toml
|
|
184
|
+
[build-dependencies]
|
|
185
|
+
tauri-build = { version = "2", features = [] }
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```rust
|
|
189
|
+
use rusqlite::Connection;
|
|
190
|
+
use tauri::Manager;
|
|
191
|
+
use std::sync::Mutex;
|
|
192
|
+
|
|
193
|
+
struct AppState {
|
|
194
|
+
db: Mutex<Connection>,
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#[tauri::command]
|
|
198
|
+
fn get_messages(state: tauri::State<AppState>) -> Result<Vec<String>, String> {
|
|
199
|
+
let conn = state.db.lock().map_err(|e| e.to_string())?;
|
|
200
|
+
// Query database...
|
|
201
|
+
Ok(vec![])
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
pub fn run() {
|
|
205
|
+
tauri::Builder::default()
|
|
206
|
+
.setup(|app| {
|
|
207
|
+
// CORRECT: Use app_data_dir for persistent data (NOT relative path)
|
|
208
|
+
let app_data = app.path().app_data_dir()
|
|
209
|
+
.expect("Failed to get app data dir");
|
|
210
|
+
std::fs::create_dir_all(&app_data).ok();
|
|
211
|
+
let db_path = app_data.join("data.db");
|
|
212
|
+
let conn = Connection::open(&db_path)
|
|
213
|
+
.expect("Failed to open database");
|
|
214
|
+
|
|
215
|
+
app.manage(AppState {
|
|
216
|
+
db: Mutex::new(conn),
|
|
217
|
+
});
|
|
218
|
+
Ok(())
|
|
219
|
+
})
|
|
220
|
+
.invoke_handler(tauri::generate_handler![get_messages])
|
|
221
|
+
.run(tauri::generate_context!())
|
|
222
|
+
.expect("error while running tauri application");
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Frontend call:**
|
|
227
|
+
```typescript
|
|
228
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
229
|
+
const messages = await invoke<string[]>('get_messages');
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Build Commands
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Desktop
|
|
236
|
+
cargo tauri build # Default platform
|
|
237
|
+
cargo tauri build --target x86_64-pc-windows-msvc # Windows x64
|
|
238
|
+
cargo tauri build --target aarch64-pc-windows-msvc # Windows ARM64
|
|
239
|
+
cargo tauri build --target aarch64-apple-darwin # macOS ARM64 (Apple Silicon)
|
|
240
|
+
cargo tauri build --target x86_64-apple-darwin # macOS x64 (Intel)
|
|
241
|
+
cargo tauri build --target universal-apple-darwin # macOS Universal Binary
|
|
242
|
+
cargo tauri build --target x86_64-unknown-linux-gnu # Linux x64
|
|
243
|
+
cargo tauri build --target aarch64-unknown-linux-gnu # Linux ARM64
|
|
244
|
+
|
|
245
|
+
# Mobile
|
|
246
|
+
cargo tauri android init # Initialize Android project (first time)
|
|
247
|
+
cargo tauri android build # Build Android APK/AAB
|
|
248
|
+
cargo tauri ios init # Initialize iOS project (first time, macOS only)
|
|
249
|
+
cargo tauri ios build # Build iOS IPA (macOS only)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Mobile Build (iOS/Android)
|
|
253
|
+
|
|
254
|
+
### Android
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Prerequisites: Android Studio, JDK 17, Android SDK 34+
|
|
258
|
+
cargo tauri android init
|
|
259
|
+
cargo tauri android build --target aarch64 # ARM64
|
|
260
|
+
cargo tauri android build --target arm # ARMv7
|
|
261
|
+
cargo tauri android build --target x86_64 # x86_64 (emulator)
|
|
262
|
+
|
|
263
|
+
# Output: src-tauri/gen/android/app/build/outputs/
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### iOS
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Prerequisites: macOS + Xcode 15+ + Apple Developer account
|
|
270
|
+
cargo tauri ios init
|
|
271
|
+
cargo tauri ios build
|
|
272
|
+
|
|
273
|
+
# Output: src-tauri/gen/apple/build/
|
|
274
|
+
# Open in Xcode for signing and distribution
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Google Play Distribution
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Build AAB (Android App Bundle — required by Play Store)
|
|
281
|
+
cargo tauri android build --aab
|
|
282
|
+
# Output: gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab
|
|
283
|
+
|
|
284
|
+
# Build APK (for direct distribution/testing)
|
|
285
|
+
cargo tauri android build --apk
|
|
286
|
+
|
|
287
|
+
# Per-architecture APKs (smaller, for testing outside Play Store)
|
|
288
|
+
cargo tauri android build --apk --split-per-abi
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### iOS App Store Distribution
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Build and open Xcode for archiving
|
|
295
|
+
cargo tauri ios build --open
|
|
296
|
+
|
|
297
|
+
# In Xcode: Product → Archive → Distribute → App Store Connect
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Physical iOS Device Development
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# Physical device requires dev server on local network
|
|
304
|
+
# 1. Connect device via Xcode → Window → Devices and Simulators
|
|
305
|
+
# 2. Run with forced IP prompt
|
|
306
|
+
cargo tauri ios dev --force-ip-prompt
|
|
307
|
+
|
|
308
|
+
# 3. Configure Vite to use TAURI_DEV_HOST:
|
|
309
|
+
# vite.config.js:
|
|
310
|
+
# const host = process.env.TAURI_DEV_HOST;
|
|
311
|
+
# server: { host: host || false, port: 1420 }
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Android Environment Variables (Required)
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# JAVA_HOME — Android Studio's bundled JBR
|
|
318
|
+
# Linux: /opt/android-studio/jbr
|
|
319
|
+
# macOS: /Applications/Android Studio.app/Contents/jbr/Contents/Home
|
|
320
|
+
# Windows: C:\Program Files\Android\Android Studio\jbr
|
|
321
|
+
|
|
322
|
+
# ANDROID_HOME
|
|
323
|
+
# Linux/macOS: $HOME/Android/Sdk
|
|
324
|
+
# Windows: %LocalAppData%\Android\Sdk
|
|
325
|
+
|
|
326
|
+
# Rust targets for Android
|
|
327
|
+
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
|
|
328
|
+
|
|
329
|
+
# Rust targets for iOS
|
|
330
|
+
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Auto-Update
|
|
334
|
+
|
|
335
|
+
```json
|
|
336
|
+
// tauri.conf.json
|
|
337
|
+
{
|
|
338
|
+
"plugins": {
|
|
339
|
+
"updater": {
|
|
340
|
+
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIH...",
|
|
341
|
+
"endpoints": [
|
|
342
|
+
"https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}"
|
|
343
|
+
]
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
```rust
|
|
350
|
+
// src-tauri/src/lib.rs
|
|
351
|
+
// ⚠️ Tauri 2.5+: UpdaterBuilder::new removed, use UpdaterExt::updater_builder
|
|
352
|
+
use tauri_plugin_updater::UpdaterExt;
|
|
353
|
+
|
|
354
|
+
fn main() {
|
|
355
|
+
tauri::Builder::default()
|
|
356
|
+
.plugin(tauri_plugin_updater::Builder::new().build())
|
|
357
|
+
.setup(|app| {
|
|
358
|
+
let handle = app.handle().clone();
|
|
359
|
+
tauri::async_runtime::spawn(async move {
|
|
360
|
+
let update = handle.updater().check().await;
|
|
361
|
+
// Handle update notification
|
|
362
|
+
});
|
|
363
|
+
Ok(())
|
|
364
|
+
})
|
|
365
|
+
.run(tauri::generate_context!())
|
|
366
|
+
.expect("error");
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Code Signing
|
|
371
|
+
|
|
372
|
+
### Windows
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# Sign the .msi or .exe after build
|
|
376
|
+
signtool sign /f certificate.pfx /p password /tr http://timestamp.digicert.com /td sha256 src-tauri/target/release/bundle/msi/*.msi
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Auto-Update Signing (Tauri 2.10+)
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# ⚠️ Environment variables RENAMED in Tauri 2.10:
|
|
383
|
+
# OLD: TAURI_PRIVATE_KEY, TAURI_PRIVATE_KEY_PATH, TAURI_PRIVATE_KEY_PASSWORD
|
|
384
|
+
# NEW: TAURI_SIGNING_PRIVATE_KEY, TAURI_SIGNING_PRIVATE_KEY_PATH, TAURI_SIGNING_PRIVATE_KEY_PASSWORD
|
|
385
|
+
export TAURI_SIGNING_PRIVATE_KEY="dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIH..."
|
|
386
|
+
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### macOS
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
// tauri.conf.json
|
|
393
|
+
{
|
|
394
|
+
"bundle": {
|
|
395
|
+
"macOS": {
|
|
396
|
+
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)",
|
|
397
|
+
"entitlements": "entitlements.plist"
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# Notarize after build
|
|
405
|
+
xcrun notarytool submit src-tauri/target/release/bundle/dmg/*.dmg \
|
|
406
|
+
--apple-id your@email.com \
|
|
407
|
+
--password app-specific-password \
|
|
408
|
+
--team-id TEAM_ID \
|
|
409
|
+
--wait
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Common Pitfalls
|
|
413
|
+
|
|
414
|
+
| Issue | Fix |
|
|
415
|
+
|-------|-----|
|
|
416
|
+
| Windows missing WebView2 | Pre-installed on Win10 21H2+. For older: download from developer.microsoft.com |
|
|
417
|
+
| Linux compile failure | `sudo apt install libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev` |
|
|
418
|
+
| macOS notarization | Requires Apple Developer ID ($99/year) + notarytool |
|
|
419
|
+
| Slow Rust compilation | First build 5–15 min; use `cargo tauri build --debug` for faster dev builds |
|
|
420
|
+
| SPA route 404 on reload | Configure `app.security.csp` in tauri.conf.json; use hash-based routing |
|
|
421
|
+
| Permission denied in production | Declare capabilities in `src-tauri/capabilities/default.json` |
|
|
422
|
+
| Database path wrong | Use `app.path().app_data_dir()` not relative paths |
|
|
423
|
+
| Mobile build fails | Run `cargo tauri android/ios init` first; check SDK/NDK paths |
|
|
424
|
+
| Auto-update not working | Ensure `pubkey` matches signing key; check endpoint URL format; env vars renamed in v2.10 (see above) |
|
|
425
|
+
| `invoke` returns undefined | Check Rust command name matches `tauri::generate_handler![]` |
|
|
426
|
+
| WebView2 crash on old Windows | Set `"windows": {"webviewInstallMode": {"type": "embedBootstrapper"}}` in tauri.conf.json |
|
|
427
|
+
| Signer env vars not working | Tauri 2.10+ renamed: `TAURI_SIGNING_PRIVATE_KEY` (was `TAURI_PRIVATE_KEY`) |
|
|
428
|
+
| `WebviewAttributes` import fails | Removed from `tauri` crate in v2.5; import from `tauri::webview::WebviewAttributes` instead |
|