Install
$ agentstack add skill-impertio-studio-tauri-2-claude-skill-package-tauri-core-runtime ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
tauri-core-runtime
Quick Reference
Builder Method Summary (Tauri 2.x)
| Method | Purpose | Example | |--------|---------|---------| | Builder::default() | Create default builder | tauri::Builder::default() | | .setup(F) | App initialization hook | .setup(\|app\| { Ok(()) }) | | .invoke_handler(F) | Register command handlers | .invoke_handler(generate_handler![cmd1]) | | .manage(T) | Register managed state | .manage(MyState::default()) | | .plugin(P) | Register a plugin | .plugin(my_plugin::init()) | | .menu(F) | Set application menu | .menu(\|app\| MenuBuilder::new(app).build()) | | .on_window_event(F) | Window event handler | .on_window_event(\|window, event\| { }) | | .on_menu_event(F) | Menu event handler | .on_menu_event(\|app, event\| { }) | | .on_webview_event(F) | Webview event handler | .on_webview_event(\|webview, event\| { }) | | .on_page_load(F) | Page load handler | .on_page_load(\|webview, payload\| { }) | | .on_tray_icon_event(F) | Tray icon event handler | .on_tray_icon_event(\|app, event\| { }) | | .any_thread() | Allow running on non-main thread | .any_thread() | | .build(Context) | Build without running (returns App) | .build(generate_context!()) | | .run(Context) | Build and run the app | .run(generate_context!()) |
Manager Trait Key Methods
| Method | Returns | Available On | |--------|---------|-------------| | app_handle() | &AppHandle | App, AppHandle, Window, WebviewWindow, Webview | | state::() | State | All Manager implementors | | try_state::() | Option> | All Manager implementors | | manage(T) | bool | All Manager implementors | | get_webview_window(label) | Option> | All Manager implementors | | webview_windows() | HashMap> | All Manager implementors | | get_window(label) | Option> | All Manager implementors | | get_focused_window() | Option> | All Manager implementors | | config() | &Config | All Manager implementors | | path() | &PathResolver | All Manager implementors | | package_info() | &PackageInfo | All Manager implementors |
AppHandle Properties
| Property | Description | |----------|-------------| | Clone | Can be cloned freely | | Send + Sync | Safe to pass across threads | | Implements Manager | Full access to state, windows, config | | Implements Emitter | Can emit events | | Implements Listener | Can listen for events |
Critical Warnings
NEVER call .invoke_handler() more than once on a Builder -- only the last call takes effect. Put ALL commands in a single generate_handler![].
NEVER use Arc to wrap managed state -- Tauri already wraps state in Arc internally. Use app.manage(data), not app.manage(Arc::new(data)).
NEVER access managed state with the wrong wrapper type -- State when you registered Mutex causes a runtime panic, not a compile error.
ALWAYS clone AppHandle before moving it into a thread or async block -- app.handle().clone() is the correct pattern.
ALWAYS use #[cfg_attr(mobile, tauri::mobile_entry_point)] on the run() function in lib.rs when targeting mobile platforms.
NEVER perform heavy I/O in setup() synchronously without spawning a thread -- it blocks app startup.
Essential Patterns
Pattern 1: Standard Application Entry Point (Tauri 2.x)
// src-tauri/src/lib.rs
mod commands;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(AppState::default())
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![
commands::greet,
commands::fetch_data,
])
.setup(|app| {
let handle = app.handle().clone();
// Initialization logic here
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
// src-tauri/src/main.rs
fn main() {
app_lib::run();
}
Pattern 2: The setup() Hook
The setup hook runs after the app is initialized but before windows are shown. It receives &mut App and returns Result>. Any error aborts app startup.
.setup(|app| {
// 1. Access AppHandle for thread-safe operations
let handle = app.handle().clone();
// 2. Register state that depends on app paths
let db_path = app.path().app_data_dir()?.join("data.db");
app.manage(Database::new(&db_path)?);
// 3. Spawn a background thread (uses cloned AppHandle)
std::thread::spawn(move || {
loop {
handle.emit("heartbeat", ()).unwrap();
std::thread::sleep(std::time::Duration::from_secs(30));
}
});
// 4. Create additional windows programmatically
let _settings = tauri::webview::WebviewWindowBuilder::new(
app,
"settings",
tauri::WebviewUrl::App("settings.html".into()),
)
.title("Settings")
.inner_size(600.0, 400.0)
.visible(false)
.build()?;
Ok(())
})
Pattern 3: AppHandle in Threads and Async Blocks
AppHandle is Clone + Send + Sync, making it the primary handle for background work.
// In setup() or from a command
let handle = app.handle().clone();
// Std thread
std::thread::spawn(move || {
let state = handle.state::();
handle.emit("background-update", "data").unwrap();
if let Some(window) = handle.get_webview_window("main") {
window.set_title("Updated").unwrap();
}
});
// Tokio async task
let handle = app.handle().clone();
tokio::spawn(async move {
let result = some_async_work().await;
handle.emit("async-done", result).unwrap();
});
Pattern 4: Window Event Callbacks
.on_window_event(|window, event| {
match event {
tauri::WindowEvent::CloseRequested { api, .. } => {
// Prevent close and hide instead (e.g., tray app)
api.prevent_close();
window.hide().unwrap();
}
tauri::WindowEvent::Focused(focused) => {
if *focused {
println!("{} gained focus", window.label());
}
}
tauri::WindowEvent::Destroyed => {
println!("{} was destroyed", window.label());
}
_ => {}
}
})
Pattern 5: Build vs Run
Use .build() when you need access to the App instance before running, or when you need the run callback for lifecycle events like exit.
// .run() -- simple, no run callback
tauri::Builder::default()
.run(tauri::generate_context!())
.expect("error running app");
// .build() + .run() -- access to RunEvent for exit handling
let app = tauri::Builder::default()
.build(tauri::generate_context!())
.expect("error building app");
app.run(|app_handle, event| {
match event {
tauri::RunEvent::ExitRequested { api, .. } => {
// Prevent exit (e.g., keep running in tray)
api.prevent_exit();
}
tauri::RunEvent::Exit => {
// Final cleanup before process ends
println!("Application exiting");
}
_ => {}
}
});
Pattern 6: Exit and Restart
// Exit from a command
#[tauri::command]
fn quit_app(app: tauri::AppHandle) {
app.exit(0); // 0 = success exit code
}
// Restart (requires tauri-plugin-process)
#[tauri::command]
fn restart_app(app: tauri::AppHandle) {
app.restart();
}
// Frontend exit/restart (requires @tauri-apps/plugin-process)
import { exit, relaunch } from '@tauri-apps/plugin-process';
await exit(0);
await relaunch();
Async Runtime
Tauri 2.x uses tokio as the async runtime. Async commands are automatically spawned on the tokio runtime -- you do NOT need to configure tokio yourself.
The tauri::async_runtime module provides direct access when needed:
tauri::async_runtime::spawn(async {
// Runs on the tokio runtime
});
ALWAYS use async commands for I/O, network, or long-running operations. Sync commands run on the main thread and will freeze the UI if they block.
ALWAYS use #[tauri::command(async)] on a sync function if you want it to run on the async runtime instead of the main thread:
#[tauri::command(async)]
fn heavy_sync_computation(data: Vec) -> Vec {
// Runs on tokio runtime, not main thread
expensive_transform(data)
}
WindowEvent Variants (Tauri 2.x)
| Variant | Fields | Description | |---------|--------|-------------| | Resized | PhysicalSize | Window client area resized | | Moved | PhysicalPosition | Window position changed | | CloseRequested | api: CloseRequestApi | Close requested; call api.prevent_close() to cancel | | Destroyed | -- | Window has been destroyed | | Focused | bool | true = gained focus, false = lost | | ScaleFactorChanged | scale_factor, new_inner_size | DPI/display scale changed | | DragDrop | DragDropEvent | File drag-and-drop event | | ThemeChanged | Theme | System theme changed (not on Linux) |
Reference Links
- [references/methods.md](references/methods.md) -- Builder methods, Manager trait methods, AppHandle methods
- [references/examples.md](references/examples.md) -- Lifecycle patterns, setup hook, background tasks
- [references/anti-patterns.md](references/anti-patterns.md) -- Lifecycle mistakes and how to avoid them
Official Sources
- https://v2.tauri.app/develop/
- https://docs.rs/tauri/latest/tauri/struct.Builder.html
- https://docs.rs/tauri/latest/tauri/struct.AppHandle.html
- https://docs.rs/tauri/latest/tauri/trait.Manager.html
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Tauri-2-Claude-Skill-Package
- License: MIT
- Homepage: https://github.com/OpenAEC-Foundation
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.