Skip to main content
tauri-v2 Tauri v2 cross-platform app development with Rust backend. Use when configuring tauri.conf.json, implementing Rust commands (#[tauri::command]), setting up IPC patterns (invoke, emit, channels), configuring permissions/capabilities, troubleshooting build issues, or deploying desktop/mobile apps. Triggers on Tauri, src-tauri, invoke, emit, capabilities.json.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/Sheshiyer/skill-clusters --skill tauri-v2コマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... このリポジトリの他の Skills Arcplume runs Grok through the Grok Build CLI's own OAuth-authenticated session (grok login) for image generation, with strict preflight validation, secret-safe handling, and headless CLI-driven execution -- no separate XAI_API_KEY billing. Video falls back to the billed xAI API. USE WHEN a user wants to generate an image via a locally logged-in Grok Build CLI session, e.g. 'generate an image with grok', 'use grok build', or 'use my logged-in grok session'.
Shared reference for the Selemene cluster: the two report surfaces (deterministic Rust reports vs. narrative witness-pipeline readings), the @selemene/bridge CLI contract, the output manifest format, and non-prescriptive witnessing tone. USE WHEN deciding which Selemene surface to invoke or when routing between birth/compatibility/transit reports and solo/dyadic readings.
Route Selemene Engine tasks to the right surface: deterministic reports (birth/compatibility/transit) via selemene-core and the @selemene/bridge CLI, or narrative witness readings via selemene-report. USE WHEN the user wants anything under the Selemene/Noesis umbrella but has not named the exact surface.
name tauri-v2 description Tauri v2 cross-platform app development with Rust backend. Use when configuring tauri.conf.json, implementing Rust commands (#[tauri::command]), setting up IPC patterns (invoke, emit, channels), configuring permissions/capabilities, troubleshooting build issues, or deploying desktop/mobile apps. Triggers on Tauri, src-tauri, invoke, emit, capabilities.json. cluster tauri version 1.0.0
Tauri v2 Development Skill
Build cross-platform desktop and mobile apps with web frontends and Rust backends.
Before You Start
This skill prevents 8+ common errors and saves ~60% tokens.
Metric Without Skill With Skill Setup Time ~2 hours ~30 min Common Errors 8+ 0 Token Usage High (exploration) Low (direct patterns)
Known Issues This Skill Prevents
Permission denied errors from missing capabilities
IPC failures from unregistered commands in generate_handler!
State management panics from type mismatches
Mobile build failures from missing Rust targets
White screen issues from misconfigured dev URLs
Quick Start
Step 1: Create a Tauri Command
#[tauri::command]
fn greet (name: String ) -> String {
format! ("Hello, {}!" , name)
}
pub fn run () {
tauri::Builder::default ()
.invoke_handler (tauri::generate_handler![greet])
.run (tauri::generate_context!())
.expect ("error while running tauri application" );
}
Why this matters: Commands not in generate_handler![] silently fail when invoked from frontend.
Step 2: Call from Frontend import { invoke } from '@tauri-apps/api/core' ;
const greeting = await invoke<string >('greet' , { name : 'World' });
console .log (greeting);
Why this matters: Use @tauri-apps/api/core (not @tauri-apps/api/tauri - that's v1 API).
Step 3: Add Required Permissions
{
"$schema" : "../gen/schemas/desktop-schema.json" ,
"identifier" : "default" ,
"windows" : [ "main" ] ,
"permissions" : [ "core:default" ]
}
Why this matters: Tauri v2 denies everything by default - explicit permissions required for all operations.
Critical Rules
Always Do
Register every command in tauri::generate_handler![cmd1, cmd2, ...]
Return Result<T, E> from commands for proper error handling
Use Mutex<T> for shared state accessed from multiple commands
Add capabilities before using any plugin features
Use lib.rs for shared code (required for mobile builds)
Never Do
Never use borrowed types (&str) in async commands - use owned types
Never block the main thread - use async for I/O operations
Never hardcode paths - use Tauri path APIs (app.path())
Never skip capability setup - even "safe" operations need permissions
Common Mistakes Wrong - Borrowed type in async:
#[tauri::command]
async fn bad (name: &str ) -> String {
name.to_string ()
}
#[tauri::command]
async fn good (name: String ) -> String {
name
}
Why: Async commands cannot borrow data across await points; Tauri requires owned types for async command parameters.
Known Issues Prevention Issue Root Cause Solution "Command not found" Missing from generate_handler! Add command to handler macro "Permission denied" Missing capability Add to capabilities/default.json State panic on access Type mismatch in State<T> Use exact type from .manage() White screen on launch Frontend not building Check beforeDevCommand in config IPC timeout Blocking async command Remove blocking code or use spawn Mobile build fails Missing Rust targets Run rustup target add <target>
Configuration Reference
tauri.conf.json {
"$schema" : "./gen/schemas/desktop-schema.json" ,
"productName" : "my-app" ,
"version" : "1.0.0" ,
"identifier" : "com.example.myapp" ,
"build" : {
"devUrl" : "http://localhost:5173" ,
"frontendDist" : "../dist" ,
"beforeDevCommand" : "npm run dev" ,
"beforeBuildCommand" : "npm run build"
} ,
"app" : {
"windows" : [ {
"label" : "main" ,
"title" : "My App" ,
"width" : 800 ,
"height" : 600
} ] ,
"security" : {
"csp" : "default-src 'self'; img-src 'self' data:" ,
"capabilities" : [ "default" ]
}
} ,
"bundle" : {
"active" : true ,
"targets" : "all" ,
"icon" : [ "icons/icon.icns" , "icons/icon.ico" , "icons/icon.png" ]
}
}
build.devUrl: Must match your frontend dev server port
app.security.capabilities: Array of capability file identifiers
Cargo.toml [package]
name = "app"
version = "0.1.0"
edition = "2021"
[lib]
name = "app_lib"
crate-type = ["staticlib" , "cdylib" , "rlib" ]
[build-dependencies]
tauri-build = { version = "2" , features = [] }
[dependencies]
tauri = { version = "2" , features = [] }
serde = { version = "1" , features = ["derive" ] }
serde_json = "1"
[lib] section: Required for mobile builds
crate-type: Must include all three types for cross-platform
Common Patterns
Error Handling Pattern use thiserror::Error;
#[derive(Debug, Error)]
enum AppError {
#[error("IO error: {0}" )]
Io (#[from] std::io::Error),
#[error("Not found: {0}" )]
NotFound (String ),
}
impl serde ::Serialize for AppError {
fn serialize <S>(&self , serializer: S) -> Result <S::Ok , S::Error>
where S: serde::ser::Serializer {
serializer.serialize_str (self .to_string ().as_ref ())
}
}
#[tauri::command]
fn risky_operation () -> Result <String , AppError> {
Ok ("success" .into ())
}
State Management Pattern use std::sync::Mutex;
use tauri::State;
struct AppState {
counter: u32 ,
}
#[tauri::command]
fn increment (state: State<'_ , Mutex<AppState>>) -> u32 {
let mut s = state.lock ().unwrap ();
s.counter += 1 ;
s.counter
}
tauri::Builder::default ()
.manage (Mutex::new (AppState { counter: 0 }))
Event Emission Pattern use tauri::Emitter;
#[tauri::command]
fn start_task (app: tauri::AppHandle) {
std::thread::spawn (move || {
app.emit ("task-progress" , 50 ).unwrap ();
app.emit ("task-complete" , "done" ).unwrap ();
});
}
import { listen } from '@tauri-apps/api/event' ;
const unlisten = await listen ('task-progress' , (e ) => {
console .log ('Progress:' , e.payload );
});
Channel Streaming Pattern use tauri::ipc::Channel;
#[derive(Clone, serde::Serialize)]
#[serde(tag = "event" , content = "data" )]
enum DownloadEvent {
Progress { percent: u32 },
Complete { path: String },
}
#[tauri::command]
async fn download (url: String , on_event: Channel<DownloadEvent>) {
for i in 0 ..=100 {
on_event.send (DownloadEvent::Progress { percent: i }).unwrap ();
}
on_event.send (DownloadEvent::Complete { path: "/downloads/file" .into () }).unwrap ();
}
import { invoke, Channel } from '@tauri-apps/api/core' ;
const channel = new Channel <DownloadEvent >();
channel.onmessage = (msg ) => console .log (msg.event , msg.data );
await invoke ('download' , { url : 'https://...' , onEvent : channel });
Bundled Resources
References
Note: For deep dives on specific topics, see the reference files above.
Dependencies
Required Package Version Purpose @tauri-apps/cli^2.0.0 CLI tooling @tauri-apps/api^2.0.0 Frontend APIs tauri^2.0.0 Rust core tauri-build^2.0.0 Build scripts
Optional (Plugins) Package Version Purpose tauri-plugin-fs^2.0.0 File system access tauri-plugin-dialog^2.0.0 Native dialogs tauri-plugin-shell^2.0.0 Shell commands, open URLs tauri-plugin-http^2.0.0 HTTP client tauri-plugin-store^2.0.0 Key-value storage
Official Documentation
Troubleshooting
White Screen on Launch Symptoms: App launches but shows blank white screen
Verify devUrl matches your frontend dev server port
Check beforeDevCommand runs your dev server
Open DevTools (Cmd+Option+I / Ctrl+Shift+I) to check for errors
Command Returns Undefined Symptoms: invoke() returns undefined instead of expected value
Verify command is in generate_handler![]
Check Rust command actually returns a value
Ensure argument names match (camelCase in JS, snake_case in Rust by default)
Mobile Build Failures Symptoms: Android/iOS build fails with missing target
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
Setup Checklist Before using this skill, verify: