This skill should be used when the user wants to create, scaffold, implement, test, or debug a Tauri v2 plugin, or asks about Tauri plugin commands, TypeScript bindings, Rust backend patterns, or plugin structure. Covers the full Tauri v2 plugin development lifecycle.
From tauri-plugin-devnpx claudepluginhub utakatakyosui/c2lab --plugin tauri-plugin-devThis skill uses the workspace's default tool permissions.
references/mobile-support.mdreferences/plugin-structure.mdreferences/rust-patterns.mdreferences/testing-debugging.mdreferences/typescript-bindings.mdGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Reviews prose for communication issues impeding comprehension, outputs minimal fixes in a three-column table per Microsoft Writing Style Guide. Useful for 'review prose' or 'improve prose' requests.
Tauri plugins extend Tauri applications with native capabilities. A plugin provides:
Plugins follow the naming convention tauri-plugin-<name>, with the corresponding crate name tauri-plugin-<name> and guest bindings at @tauri-apps/plugin-<name>.
# Tauri CLI v2 required
cargo install tauri-cli
cargo tauri plugin new <plugin-name>
This generates the full project structure. Alternatively, use npx @tauri-apps/cli plugin new <plugin-name>.
The CLI creates:
tauri-plugin-<name>/
├── Cargo.toml # Rust crate configuration
├── build.rs # Build script (generates permissions)
├── src/
│ ├── lib.rs # Plugin implementation (entry point)
│ ├── commands.rs # Command handlers
│ ├── models.rs # Data types (optional)
│ └── error.rs # Error types
├── permissions/
│ └── default.toml # Default permission set
├── guest-js/
│ ├── package.json
│ ├── index.ts # TypeScript API
│ └── tsconfig.json
└── examples/ # Example Tauri apps
See references/plugin-structure.md for detailed file-by-file breakdown.
Every Tauri v2 plugin uses the Builder pattern:
use tauri::plugin::{Builder, TauriPlugin};
use tauri::{Manager, Runtime};
pub use models::*;
pub use error::{Error, Result};
mod commands;
mod error;
mod models;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("<plugin-name>")
.invoke_handler(tauri::generate_handler![
commands::do_something,
])
.setup(|app, api| {
// Initialize plugin state
app.manage(MyState::default());
Ok(())
})
.build()
}
Commands are async Rust functions exposed to the frontend:
use tauri::{command, AppHandle, Runtime, State};
use crate::{MyState, Result};
#[command]
pub(crate) async fn do_something<R: Runtime>(
app: AppHandle<R>,
state: State<'_, MyState>,
payload: String,
) -> Result<String> {
// Implementation
Ok(format!("processed: {payload}"))
}
use serde::{ser::Serializer, Serialize};
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("{0}")]
Custom(String),
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where S: Serializer {
serializer.serialize_str(self.to_string().as_ref())
}
}
See references/rust-patterns.md for state management, events, and advanced patterns.
import { invoke } from '@tauri-apps/api/core';
export async function doSomething(payload: string): Promise<string> {
return await invoke<string>('plugin:<plugin-name>|do_something', {
payload,
});
}
Important: Tauri v2 uses plugin:<name>|<command> format for plugin commands.
import { listen } from '@tauri-apps/api/event';
export async function onPluginEvent(
handler: (data: MyEventData) => void,
): Promise<() => void> {
return await listen<MyEventData>('plugin:<plugin-name>//my-event', handler);
}
See references/typescript-bindings.md for full API reference, type generation, and build setup.
[package]
name = "tauri-plugin-<name>"
version = "0.1.0"
edition = "2021"
[dependencies]
tauri = { version = "2", default-features = false }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
[build-dependencies]
tauri-build = { version = "2", default-features = false, features = ["codegen"] }
// In the Tauri app's src-tauri/src/lib.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_<name>::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
# In the app's src-tauri/Cargo.toml
[dependencies]
tauri-plugin-<name> = { path = "../tauri-plugin-<name>" }
Tauri v2 requires explicit permission declarations. Create permissions/default.toml:
[default]
description = "Default permissions for plugin-<name>"
permissions = ["allow-do-something"]
The build.rs auto-generates permission types from command names:
const COMMANDS: &[&str] = &["do_something"];
fn main() {
tauri_build::mobile_entry_point_exists();
tauri_build::try_build(
tauri_build::Attributes::new()
.plugin(
tauri_build::PluginBuilder::new()
.commands(COMMANDS)
.build(),
),
)
.expect("failed to run tauri-build");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_core_logic() {
// Test plugin logic without Tauri runtime
let result = process_data("input");
assert_eq!(result, "expected");
}
}
Use the tauri::test module for testing with a mock app handle:
#[cfg(test)]
mod tests {
use tauri::test::{mock_app, MockRuntime};
#[test]
fn test_plugin_init() {
let app = mock_app();
// Test plugin integration
}
}
See references/testing-debugging.md for full testing strategies and debugging techniques.
cargo tauri plugin new <name>models.rscommands.rslib.rs invoke_handlerpermissions/guest-js/index.tsexamples/When targeting iOS or Android, extend the standard workflow with these steps:
src/desktop.rs (AppHandle-based) and src/mobile.rs (PluginHandle wrapper)#[cfg(desktop)]/#[cfg(mobile)] module declarations and branch in .setup()mobile = [] feature and [target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] sectionandroid/ (Kotlin @TauriPlugin class) and/or ios/ (Swift Plugin subclass)tauri android init / tauri ios init to generate platform directoriestauri android dev / tauri ios dev for live developmentSee references/mobile-support.md for complete Kotlin/Swift examples, permission setup, and error troubleshooting.
references/plugin-structure.md - Detailed file structure and Cargo workspace setupreferences/rust-patterns.md - State management, events, mobile support, advanced patternsreferences/typescript-bindings.md - Full TypeScript API, type generation, npm packagingreferences/testing-debugging.md - Testing strategies, logging, common errors, troubleshootingreferences/mobile-support.md - Complete iOS/Android implementation: Kotlin, Swift, permissions, errors