本文へ移動
cccskills
無料GitHub で公開

desktop-plugins-tauri

Tauri 2.x official plugin ecosystem, plugin APIs, permissions, and custom plugin development

インストール方法を見る

含まれるファイル(10)

  • SKILL.md17.3 KB
  • examples/core.md6.0 KB
  • examples/custom-plugins.md10.5 KB
  • examples/data-storage.md8.6 KB
  • examples/lifecycle.md8.4 KB
  • examples/mobile.md4.6 KB
  • examples/networking.md4.5 KB
  • examples/system.md5.6 KB
  • metadata.yaml704 B
  • reference.md11.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Tauri 2.x Plugin Ecosystem

Quick Guide: Tauri plugins follow a dual-install pattern: Cargo crate (Rust backend) + npm package (JS frontend). Every plugin must be registered with .plugin() in Rust AND have permissions granted in a capability file. Missing any step causes runtime errors, not compile errors. Custom plugins use tauri::plugin::Builder with optional mobile support (Swift/Kotlin). There are 30+ official plugins covering fs, http, dialog, store, notification, shell, updater, sql, log, stronghold, deep-link, global-shortcut, and more.

Current version: Tauri 2.x (stable). All plugins require Rust 1.77.2+.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST complete ALL four installation steps for every plugin: 1) cargo add crate, 2) npm install bindings, 3) .plugin() registration in Rust, 4) permissions in capability file -- missing any step causes runtime errors)

(You MUST scope plugin permissions in capability files -- never grant unscoped fs:allow-read-text-file or http:default without URL restrictions)

(You MUST use @tauri-apps/plugin-* npm packages for JS bindings -- not @tauri-apps/api/* which is the core API)

(You MUST use #[cfg(desktop)] guard when registering desktop-only plugins -- mobile builds will fail otherwise)

(You MUST use tauri::plugin::Builder with an init() convention when creating custom plugins -- not raw command registration)

</critical_requirements>


Auto-detection: tauri-plugin, @tauri-apps/plugin, tauri_plugin, plugin registration, .plugin(), tauri-plugin-fs, tauri-plugin-http, tauri-plugin-store, tauri-plugin-dialog, tauri-plugin-notification, tauri-plugin-shell, tauri-plugin-updater, tauri-plugin-log, tauri-plugin-sql, tauri-plugin-stronghold, tauri-plugin-deep-link, tauri-plugin-global-shortcut, tauri-plugin-autostart, tauri-plugin-clipboard-manager, tauri-plugin-window-state, tauri-plugin-single-instance, tauri-plugin-barcode-scanner, tauri-plugin-biometric, tauri-plugin-os, tauri-plugin-process, custom plugin, plugin development, npx tauri plugin new

When to use:

  • Installing and configuring official Tauri plugins
  • Using plugin JavaScript APIs from the frontend
  • Scoping plugin permissions in capability files
  • Creating custom plugins with Rust backend + optional JS API
  • Adding mobile support (Swift/Kotlin) to custom plugins
  • Choosing between plugins for a specific use case (store vs stronghold, fs vs dialog)

When NOT to use:

  • Tauri core framework patterns (commands, invoke, state, events, tray, windows -- use the framework skill)
  • Frontend framework patterns (component architecture, state management -- use respective framework skills)
  • General Rust programming not related to Tauri plugin APIs
  • Build tool or bundler configuration (separate tooling concern)

Key patterns covered:

Detailed resources:


<philosophy>

Philosophy

Tauri plugins extend the core framework with native capabilities through a dual-architecture design: a Rust backend crate providing the implementation, and an npm package providing typed JavaScript bindings. This separation enforces security -- every plugin operation must be explicitly permitted in a capability file.

Plugin architecture principles:

  • Security by default: Plugins do nothing until permissions are granted. Permissions are scoped per-window and can restrict operations to specific paths, URLs, or commands.
  • Dual install: Rust crate handles native operations; npm package provides the typed JS API. Both are required.
  • Platform awareness: Some plugins are desktop-only (shell, autostart, global-shortcut), some are mobile-only (barcode-scanner, biometric, haptics), and many work on both.
  • Convention over configuration: All official plugins follow the same four-step install pattern. Custom plugins use tauri::plugin::Builder with an init() export.

When to use plugins vs custom commands:

  • Need file system, HTTP, notifications, or other OS features? Use the official plugin.
  • Need custom business logic that runs in Rust? Write a Tauri command (framework skill).
  • Need a reusable native capability shared across projects? Write a custom plugin.

When NOT to use a plugin:

  • The JS Web API already covers the need (e.g., navigator.clipboard for simple text copy in some contexts)
  • A custom Tauri command is simpler for a one-off operation
  • The plugin is mobile-only but your app is desktop-only (or vice versa)
</philosophy>
<patterns>

Core Patterns

Pattern 1: Four-Step Plugin Installation

Every official plugin requires exactly four steps. Missing any step causes runtime errors, not compile errors.

# Step 1: Add Rust crate
cargo add tauri-plugin-store

# Step 2: Add JS bindings
npm add @tauri-apps/plugin-store

# Step 3: Register plugin in Rust (src-tauri/src/lib.rs)
# .plugin(tauri_plugin_store::Builder::new().build())

# Step 4: Add permissions to capability file (src-tauri/capabilities/main.json)
# "store:default"

Why all four steps: Cargo crate = backend implementation, npm package = typed JS bindings, .plugin() = runtime activation, capability permission = frontend authorization. Any missing piece causes a runtime error with an unhelpful message.

Shortcut: cargo tauri add <plugin> handles steps 1 and 3 automatically. You still need npm install (step 2) and permissions (step 4).

See examples/core.md for multi-plugin registration and permission scoping.


Pattern 2: Permission Scoping

Plugins operate under least-privilege. Scope permissions to specific paths, URLs, or commands.

{
  "permissions": [
    "core:default",
    {
      "identifier": "fs:allow-read-text-file",
      "allow": [{ "path": "$APPDATA/**" }]
    },
    {
      "identifier": "http:default",
      "allow": [{ "url": "https://api.example.com/**" }]
    }
  ]
}

Why scoping matters: Unscoped fs:allow-read-text-file grants access to ANY file on the system. Unscoped http:default allows requests to ANY domain. Always restrict to the minimum required scope.

See examples/core.md for shell command scoping and window-specific permissions.


Pattern 3: Desktop-Only Plugin Guard

Desktop-only plugins (shell, autostart, global-shortcut, single-instance, window-state, positioner) must be wrapped in #[cfg(desktop)] to prevent mobile build failures.

tauri::Builder::default()
    .setup(|app| {
        #[cfg(desktop)]
        {
            app.handle().plugin(tauri_plugin_autostart::init(
                tauri_plugin_autostart::MacosLauncher::LaunchAgent,
                None,
            ));
            app.handle().plugin(tauri_plugin_global_shortcut::Builder::new().build());
        }
        Ok(())
    })

Key point: Without #[cfg(desktop)], the Rust compiler will fail on mobile targets because these crates do not support iOS/Android.


Pattern 4: Store vs Stronghold vs SQL

Three storage plugins serve different needs:

PluginUse CaseEncryptionQueryPlatform
StoreApp preferences, settingsNoKey-value onlyAll
StrongholdSecrets, API keys, tokensYes (Argon2)Key-value onlyDesktop
SQLStructured data, relationsNo (app-level)Full SQL (SQLite/MySQL/Postgres)All

Decision: User preferences and simple config? Store. Sensitive credentials? Stronghold. Structured relational data? SQL.

See examples/data-storage.md for complete API examples for each.


Pattern 5: Updater with Signed Releases

The updater plugin requires cryptographic signatures -- this cannot be disabled. Updates check an endpoint, verify the signature, download, and install.

import { check } from "@tauri-apps/plugin-updater";
import { relaunch } from "@tauri-apps/plugin-process";

const update = await check();
if (update) {
  await update.downloadAndInstall((event) => {
    // event.event: "Started" | "Progress" | "Finished"
  });
  await relaunch();
}

Key point: Generate signing keys with cargo tauri signer generate. Set TAURI_SIGNING_PRIVATE_KEY during builds. The public key goes in tauri.conf.json. Losing the private key means you cannot ship updates to existing users.

See examples/lifecycle.md for endpoint JSON format and Rust API.


Pattern 6: Custom Plugin Development

Custom plugins use tauri::plugin::Builder with the init() convention.

use tauri::plugin::{Builder, TauriPlugin};
use tauri::Runtime;

#[tauri::command]
fn my_command() -> String {
    "Hello from plugin".into()
}

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![my_command])
        .setup(|app, _api| {
            // Initialize state, start background tasks
            Ok(())
        })
        .build()
}

Key points: Plugin commands are invoked as plugin:my-plugin|my_command from JS. Scaffold a full plugin project with npx @tauri-apps/cli plugin new <name>. The template includes desktop.rs, mobile.rs, permissions, and JS bindings.

See examples/custom-plugins.md for lifecycle hooks, configuration, and mobile support.

</patterns>

<decision_framework>

Decision Framework

Plugin Selection

What native capability do you need?
|
+-- File system read/write?
|   +-- tauri-plugin-fs (scoped to specific directories)
|
+-- File/folder picker dialog?
|   +-- tauri-plugin-dialog (open, save, message, ask)
|
+-- HTTP requests bypassing CORS?
|   +-- tauri-plugin-http (scope to specific domains)
|
+-- Persistent key-value storage?
|   +-- Sensitive data (tokens, keys)? -> tauri-plugin-stronghold
|   +-- App preferences/settings? -> tauri-plugin-store
|
+-- Relational/structured data?
|   +-- tauri-plugin-sql (SQLite, MySQL, PostgreSQL)
|
+-- System notifications?
|   +-- tauri-plugin-notification (check permissions first on macOS/mobile)
|
+-- Run external processes?
|   +-- tauri-plugin-shell (desktop only, scope allowed commands)
|
+-- Auto-update?
|   +-- tauri-plugin-updater (requires signed releases)
|
+-- Structured logging?
|   +-- tauri-plugin-log (targets: stdout, file, webview)
|
+-- Custom URL scheme handling?
|   +-- tauri-plugin-deep-link (configure per-platform)
|
+-- System-wide keyboard shortcuts?
|   +-- tauri-plugin-global-shortcut (desktop only)
|
+-- Launch on system startup?
|   +-- tauri-plugin-autostart (desktop only)
|
+-- Single app instance?
|   +-- tauri-plugin-single-instance (desktop only)
|
+-- Remember window position/size?
|   +-- tauri-plugin-window-state (desktop only)
|
+-- Clipboard access?
|   +-- tauri-plugin-clipboard-manager
|
+-- Mobile camera/scanner?
|   +-- tauri-plugin-barcode-scanner (mobile only)
|
+-- Biometric auth?
|   +-- tauri-plugin-biometric (mobile only)
|
+-- OS/platform info?
|   +-- tauri-plugin-os
|
+-- App restart/exit?
    +-- tauri-plugin-process

Custom Plugin vs Custom Command

Is this a reusable capability shared across projects?
+-- YES -> Custom plugin (npx @tauri-apps/cli plugin new)
+-- NO  -> Is it complex enough to need its own permission model?
    +-- YES -> Custom plugin
    +-- NO  -> Regular Tauri command (simpler, framework skill)

</decision_framework>


<red_flags>

RED FLAGS

High Priority Issues:

  • Missing any of the four installation steps (cargo, npm, .plugin(), permissions) -- causes runtime error with unhelpful message
  • Unscoped filesystem permissions (fs:allow-read-text-file without path restriction) -- grants access to entire filesystem
  • Unscoped HTTP permissions (http:default without URL pattern) -- allows requests to any domain
  • Unscoped shell execute (shell:allow-execute without command allowlist) -- allows running arbitrary commands
  • Using @tauri-apps/api/* imports for plugin functionality -- plugins use @tauri-apps/plugin-* packages
  • Registering desktop-only plugins without #[cfg(desktop)] -- breaks mobile builds
  • Losing the updater signing private key -- makes shipping updates to existing users impossible

Medium Priority Issues:

  • Using Store plugin for sensitive data (API keys, tokens) -- Store is NOT encrypted, use Stronghold
  • Not checking isPermissionGranted() before sending notifications on macOS/mobile
  • Granting shell:allow-execute when only shell:allow-open (URLs/files) is needed
  • Missing sql:allow-execute permission (default only includes read operations)
  • Forgetting to call stronghold.save() after modifications (changes are lost)

Common Mistakes:

  • Installing the cargo crate but forgetting the npm package (or vice versa)
  • Using cargo tauri add and assuming all four steps are done (npm install and permissions still needed)
  • Not scoping HTTP plugin URLs -- allows the app to make requests to arbitrary servers
  • Using the updater plugin on mobile (it is desktop-only)
  • Expecting Store data to persist across app reinstalls (store location depends on app identifier)

Gotchas & Edge Cases:

  • Plugin init variants: Some plugins use .init() (fs, dialog, shell, notification), others use Builder::new().build() (store, updater, global-shortcut, log) -- check each plugin's docs
  • Store autoSave: When autoSave: false, you must call store.save() manually. When autoSave is a number, it debounces saves by that many milliseconds.
  • SQL default permissions: Only read operations (select, load, close) are granted by default -- sql:allow-execute must be added explicitly for INSERT/UPDATE/DELETE
  • Stronghold platform: Desktop-only. Store data as Uint8Array (not strings) -- use TextEncoder/TextDecoder for string conversion
  • Deep link desktop: On desktop, deep links arrive as command-line arguments. Combine with single-instance plugin to handle links when the app is already running.
  • Global shortcut conflicts: Registering a shortcut already bound system-wide (e.g., Ctrl+C) silently fails or overrides the system binding depending on the OS
  • Window-state plugin: Automatically restores window position/size on startup with zero JS code needed -- just register the plugin
  • Plugin registration order: Does not matter. Each .plugin() call is independent.

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST complete ALL four installation steps for every plugin: 1) cargo add crate, 2) npm install bindings, 3) .plugin() registration in Rust, 4) permissions in capability file -- missing any step causes runtime errors)

(You MUST scope plugin permissions in capability files -- never grant unscoped fs:allow-read-text-file or http:default without URL restrictions)

(You MUST use @tauri-apps/plugin-* npm packages for JS bindings -- not @tauri-apps/api/* which is the core API)

(You MUST use #[cfg(desktop)] guard when registering desktop-only plugins -- mobile builds will fail otherwise)

(You MUST use tauri::plugin::Builder with an init() convention when creating custom plugins -- not raw command registration)

Failure to follow these rules will cause silent runtime errors, security vulnerabilities from unscoped permissions, or broken mobile builds.

</critical_reminders>

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

agents-inc のスキルをすべて見る

このスキルの問題を報告する