Token导航 LogoToken导航TokenDH.com
前端设计可写文件unknown未标认证来源可访问许可证需确认审计未展示

tauri-v2Tauri V2 开发

Agent Skill

tauri-v2 用于补充前端设计相关能力,适合在 Local Agent 中需要让 Agent 承接前端设计相关任务时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

461

周安装

19

下载量

150
Local Agent

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:tauri-v2(Tauri V2 开发)
来源仓库:https://smithery.ai
仓库路径:tauri-v2
安装命令:
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。当前暂无明确安装命令,请以来源页面说明为准。

简介

tauri-v2 用于补充前端设计相关能力,适合在 Local Agent 中承接前端开发任务时使用。

  • 主要支持 Tauri V2 项目的构建、调试与跨平台界面开发。
  • 可用于生成组件代码、检查 UI 实现或协助桌面应用的前端集成。
  • 安装前需确认项目是否兼容 V2 版本,并评估是否会触发本地编译或系统调用。
  • 建议结合官方文档验证功能范围与潜在风险。

SKILL.md

Tauri 2.0 Desktop App Development

This skill provides guidance for building professional cross-platform desktop applications using Tauri 2.0 with a Rust backend and modern React frontend following MVVM architecture.

When to Use This Skill

  • Building cross-platform desktop apps (Windows, macOS, Linux)
  • Migrating from Electron to Tauri for smaller bundle size
  • Creating secure, performant native apps with web technologies
  • Implementing complex state management between Rust and React
[!CAUTION] This skill is for Tauri 2.0 only. Tauri 1.x uses different APIs and configuration.

Prerequisites

  • Rust: Install via rustup
  • Node.js: 18+ LTS
  • Platform tools:

- macOS: Xcode Command Line Tools - Windows: Visual Studio Build Tools + WebView2 - Linux: webkit2gtk, libayatana-appindicator

Project Setup

Quick Start

# Create new project with React + TypeScript
npm create tauri-app@latest my-app -- --template react-ts
cd my-app

# Install frontend dependencies
npm install zustand react-router-dom
npm install tailwindcss @tailwindcss/vite -D

# Run development
npm run tauri dev

Tailwind CSS 4 Setup

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});
/* src/styles/globals.css */
@import "tailwindcss";

@theme {
  --color-primary: oklch(0.6 0.2 250);
  --color-secondary: oklch(0.7 0.15 180);
  --font-sans: "Inter", system-ui, sans-serif;
}

Rust Backend Architecture

Module Organization

src-tauri/src/
├── main.rs              # Entry point (minimal)
├── lib.rs               # App builder, state/plugin registration
├── commands/            # Tauri commands by feature
│   ├── mod.rs
│   ├── file.rs
│   └── settings.rs
├── services/            # Business logic (pure Rust)
│   ├── mod.rs
│   └── storage.rs
├── models/              # Data structures
│   └── mod.rs
├── state/               # App state management
│   └── mod.rs
├── plugins/             # Custom Tauri plugins
│   └── mod.rs
└── error.rs             # Custom error types

Command Patterns

// commands/file.rs
use tauri::State;
use crate::{state::AppState, error::AppError};

#[tauri::command]
pub async fn read_file(
    path: String,
    state: State<'_, AppState>,
) -> Result<String, String> {
    std::fs::read_to_string(&path)
        .map_err(|e| format!("Failed to read file: {}", e))
}

#[tauri::command]
pub async fn save_file(
    path: String,
    content: String,
) -> Result<(), String> {
    std::fs::write(&path, &content)
        .map_err(|e| format!("Failed to save file: {}", e))
}

Error Handling

// error.rs
use serde::Serialize;

#[derive(Debug, Serialize)]
pub enum AppError {
    Io(String),
    Database(String),
    Validation(String),
    NotFound(String),
}

impl From<std::io::Error> for AppError {
    fn from(err: std::io::Error) -> Self {
        AppError::Io(err.to_string())
    }
}

// Convert to Tauri invoke error
impl From<AppError> for tauri::ipc::InvokeError {
    fn from(err: AppError) -> Self {
        tauri::ipc::InvokeError::from(serde_json::to_string(&err).unwrap())
    }
}

State Management

// state/mod.rs
use std::sync::Mutex;
use serde::{Deserialize, Serialize};

#[derive(Default)]
pub struct AppState {
    pub settings: Mutex<AppSettings>,
    pub cache: Mutex<Vec<String>>,
}

#[derive(Default, Serialize, Deserialize, Clone)]
pub struct AppSettings {
    pub theme: String,
    pub language: String,
}

// lib.rs - Register state
pub fn run() {
    tauri::Builder::default()
        .manage(AppState::default())
        .invoke_handler(tauri::generate_handler![
            commands::file::read_file,
            commands::file::save_file,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Permissions & Security

Capabilities (Tauri 2.0)

Tauri 2.0 uses a capability-based security model. Define permissions in src-tauri/capabilities/:

// src-tauri/capabilities/default.json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default capabilities for the app",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "fs:default",
    "dialog:default",
    "shell:allow-open"
  ]
}

Permission Scopes

// Fine-grained file system access
{
  "permissions": [
    {
      "identifier": "fs:allow-read",
      "allow": [
        { "path": "$APPDATA/**" },
        { "path": "$DOCUMENT/**" }
      ]
    },
    {
      "identifier": "fs:allow-write",
      "allow": [
        { "path": "$APPDATA/**" }
      ]
    }
  ]
}

Security Best Practices

PracticeImplementation
Minimal permissionsOnly request what you need
Input validationValidate all frontend data in Rust
Path traversal preventionUse tauri::path APIs, not raw strings
No dangerousRemoteDomainIpcAccessAvoid unless absolutely necessary
CSP headersConfigure in tauri.conf.json
// tauri.conf.json - Security settings
{
  "app": {
    "security": {
      "csp": "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'"
    }
  }
}

Plugins

Official Plugins

Install via npm + Cargo:

# Dialog plugin
npm install @tauri-apps/plugin-dialog
cargo add tauri-plugin-dialog -F tauri-plugin-dialog/unstable

# File system plugin
npm install @tauri-apps/plugin-fs
cargo add tauri-plugin-fs

# Store plugin (persistent storage)
npm install @tauri-apps/plugin-store
cargo add tauri-plugin-store

Register Plugins

// lib.rs
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_fs::init())
        .plugin(tauri_plugin_store::Builder::default().build())
        .invoke_handler(tauri::generate_handler![/* commands */])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Using Plugins in Frontend

// Dialog
import { open, save } from '@tauri-apps/plugin-dialog';

const filePath = await open({
  multiple: false,
  filters: [{ name: 'Text', extensions: ['txt', 'md'] }],
});

// File system
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';

const content = await readTextFile(filePath);
await writeTextFile(filePath, newContent);

// Store (persistent key-value)
import { Store } from '@tauri-apps/plugin-store';

const store = await Store.load('settings.json');
await store.set('theme', 'dark');
const theme = await store.get<string>('theme');

Custom Plugin

// plugins/mod.rs
use tauri::{
    plugin::{Builder, TauriPlugin},
    Runtime,
};

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("my-plugin")
        .invoke_handler(tauri::generate_handler![plugin_command])
        .build()
}

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

Build & Distribution

Development

npm run tauri dev           # Hot-reload development
npm run tauri dev -- --release  # Test release build

Production Build

npm run tauri build         # Build for current platform

Build Configuration

// tauri.conf.json
{
  "productName": "My App",
  "version": "1.0.0",
  "identifier": "com.mycompany.myapp",
  "build": {
    "beforeBuildCommand": "npm run build",
    "beforeDevCommand": "npm run dev",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist"
  },
  "bundle": {
    "active": true,
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ],
    "macOS": {
      "minimumSystemVersion": "10.13"
    },
    "windows": {
      "certificateThumbprint": null,
      "timestampUrl": ""
    }
  }
}

Platform-Specific Builds

# Cross-compile (requires toolchain)
npm run tauri build -- --target x86_64-pc-windows-msvc
npm run tauri build -- --target aarch64-apple-darwin
npm run tauri build -- --target x86_64-unknown-linux-gnu

Auto-Updater

npm install @tauri-apps/plugin-updater
cargo add tauri-plugin-updater
// lib.rs
.plugin(tauri_plugin_updater::Builder::default().build())
// capabilities/default.json
{
  "permissions": ["updater:default"]
}

Frontend Architecture (MVVM)

Folder Structure

src/
├── main.tsx                 # Entry point
├── App.tsx                  # Router setup
├── router/                  # Route definitions
│   └── index.tsx
├── views/                   # View layer (pages)
│   ├── Home/
│   │   ├── index.tsx
│   │   └── HomeView.tsx
│   └── Settings/
│       └── index.tsx
├── viewmodels/              # ViewModel layer (hooks)
│   ├── useHomeViewModel.ts
│   └── useSettingsViewModel.ts
├── models/                  # Model layer (types)
│   └── index.ts
├── stores/                  # Zustand stores
│   └── useAppStore.ts
├── services/                # Tauri bridge
│   └── tauriService.ts
├── components/              # Reusable UI
│   └── Button/
├── hooks/                   # Custom hooks
└── styles/
    └── globals.css

MVVM Pattern

LayerResponsibilityExample
ModelData types, storesmodels/, stores/
ViewUI rendering (dumb)views/, components/
ViewModelLogic, state bindingviewmodels/ hooks

Zustand Store

// stores/useAppStore.ts
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';

interface AppState {
  theme: 'light' | 'dark';
  sidebarOpen: boolean;
  setTheme: (theme: 'light' | 'dark') => void;
  toggleSidebar: () => void;
}

export const useAppStore = create<AppState>()(
  persist(
    (set) => ({
      theme: 'dark',
      sidebarOpen: true,
      setTheme: (theme) => set({ theme }),
      toggleSidebar: () => set((s) => ({ sidebarOpen: !s.sidebarOpen })),
    }),
    {
      name: 'app-storage',
      storage: createJSONStorage(() => localStorage),
    }
  )
);

Tauri Bridge Service

// services/tauriService.ts
import { invoke } from '@tauri-apps/api/core';

export const tauriService = {
  async readFile(path: string): Promise<string> {
    return invoke<string>('read_file', { path });
  },

  async saveFile(path: string, content: string): Promise<void> {
    return invoke('save_file', { path, content });
  },

  async getSettings(): Promise<AppSettings> {
    return invoke<AppSettings>('get_settings');
  },
};

ViewModel Hook

// viewmodels/useHomeViewModel.ts
import { useState, useEffect, useCallback } from 'react';
import { tauriService } from '../services/tauriService';
import { useAppStore } from '../stores/useAppStore';

export function useHomeViewModel() {
  const [files, setFiles] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const { theme } = useAppStore();

  const loadFiles = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await tauriService.listFiles();
      setFiles(data);
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unknown error');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadFiles();
  }, [loadFiles]);

  return { files, loading, error, theme, loadFiles };
}

View Component

// views/Home/HomeView.tsx
import { useHomeViewModel } from '../../viewmodels/useHomeViewModel';

export function HomeView() {
  const { files, loading, error, loadFiles } = useHomeViewModel();

  if (loading) return <div className="animate-pulse">Loading...</div>;
  if (error) return <div className="text-error">{error}</div>;

  return (
    <div className="p-4">
      <h1 className="text-2xl font-bold text-primary">Files</h1>
      <ul className="mt-4 space-y-2">
        {files.map((file) => (
          <li key={file} className="p-2 bg-surface rounded">
            {file}
          </li>
        ))}
      </ul>
      <button onClick={loadFiles} className="mt-4 btn-primary">
        Refresh
      </button>
    </div>
  );
}

React Router Setup

// router/index.tsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { lazy, Suspense } from 'react';

const Home = lazy(() => import('../views/Home'));
const Settings = lazy(() => import('../views/Settings'));

const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/settings', element: <Settings /> },
]);

export function AppRouter() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <RouterProvider router={router} />
    </Suspense>
  );
}

Decision Tree

What do you need?
├── Create new project
│   └── npm create tauri-app@latest -- --template react-ts
├── Add Rust command
│   └── Create in commands/, register in lib.rs
├── Add plugin
│   ├── Official → npm install + cargo add
│   └── Custom → Create in plugins/
├── Manage permissions
│   └── Edit capabilities/*.json
├── Manage frontend state
│   └── Use Zustand stores/
├── Call Rust from React
│   └── Use tauriService bridge
└── Build for production
    └── npm run tauri build

Common Pitfalls

IssueSolution
Commands not foundRegister in generate_handler![]
Permission deniedAdd to capabilities/*.json
State not updatingCheck Mutex lock is released
Build fails on CIInstall platform dependencies
Large bundle sizeEnable strip and lto in Cargo.toml

Resources

Examples

- Commands - Command patterns - State - State management - Error Handling - Error types

  • React Frontend:

- MVVM Structure - Architecture guide - Zustand Patterns - Store patterns - Tauri Hooks - Custom hooks

Templates

External Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Local Agent

98.34%
按下载量换算148

安全审计

暂无安全审计结果可展示。

权限和风险

可写文件

该 Skill 可能写入或修改本地文件,使用前需要确认目标目录和修改范围。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills