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명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? 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: