# How to Extend Clash Nyanpasu with Tauri Plugins: A Complete Developer Guide

> Extend Clash Nyanpasu with Tauri plugins. Integrate native features like clipboard access and system notifications by registering Rust backend plugins and using TypeScript SDKs in your React frontend. Full developer guide.

- Repository: [Nyanpasu/clash-nyanpasu](https://github.com/libnyanpasu/clash-nyanpasu)
- Tags: how-to-guide
- Published: 2026-03-06

---

**TLDR:** You can extend Clash Nyanpasu by registering Tauri plugins in the Rust backend ([`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs)) and consuming them via TypeScript SDKs in the React frontend, enabling native capabilities like clipboard management and system notifications without modifying core proxy logic.

Clash Nyanpasu is a modern desktop proxy client built on the Tauri framework, combining a Rust-based backend with a React frontend. The Tauri plugin system allows developers to add native system capabilities—such as clipboard access, file system operations, and global shortcuts—by integrating official or custom plugins through a standardized IPC layer.

## Architecture Overview

The application separates concerns into three distinct layers that interact through Tauri's plugin bridge:

- **Rust Backend**: Handles the Tauri runtime and plugin registration in [`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs). The [`Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/Cargo.toml) file at [`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml) (lines 200-209) declares plugin dependencies like `tauri-plugin-clipboard-manager = "2.2"` and `tauri-plugin-notification = "2.2"`.

- **Configuration**: The [`backend/tauri/tauri.conf.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/tauri.conf.json) file contains plugin-specific settings, such as the updater configuration (lines 71-81), where endpoints and public keys are defined under the `"plugins"` key.

- **React Frontend**: Consumes plugins through dedicated SDKs. For example, [`frontend/nyanpasu/src/utils/notification.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/utils/notification.ts) demonstrates how the notification plugin is imported and invoked using `@tauri-apps/plugin-notification`.

## Adding a New Tauri Plugin to the Backend

To add native functionality, you must register the plugin in the Rust codebase and expose it to the frontend.

### Declare the Dependency

Add the plugin crate to [`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml), matching the version used by other plugins (typically `2.2`):

```toml
[dependencies]
tauri-plugin-clipboard-manager = "2.2"
tauri-plugin-fs = "2.2"

```

### Register the Plugin in Rust

Open [`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs) and initialize the plugin within the Tauri builder chain:

```rust
use tauri_plugin_clipboard_manager::init as init_clipboard;
use tauri_plugin_notification::init as init_notification;

fn main() {
    tauri::Builder::default()
        .plugin(init_clipboard())
        .plugin(init_notification())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

```

This pattern follows the existing implementation used for the updater and shell plugins in the repository.

### Configure Plugin Options

If the plugin requires runtime configuration, add a section to [`backend/tauri/tauri.conf.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/tauri.conf.json) under the `"plugins"` object:

```json
{
  "plugins": {
    "updater": {
      "pubkey": "...",
      "endpoints": ["...", "..."]
    },
    "clipboard-manager": {
      "read_text": true
    }
  }
}

```

## Consuming Plugins from the React Frontend

Once registered in Rust, plugins are accessible from the TypeScript codebase through dedicated npm packages.

### Install the JavaScript SDK

Install the corresponding frontend package. The repository uses `pnpm` and lists these in [`frontend/nyanpasu/package.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/package.json):

```bash
pnpm add -D @tauri-apps/plugin-clipboard-manager
pnpm add -D @tauri-apps/plugin-notification

```

### Invoke Plugin APIs

Create utility modules to wrap plugin functionality. Following the pattern in [`frontend/nyanpasu/src/utils/notification.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/utils/notification.ts), implement clipboard operations:

```typescript
import { readText, writeText } from '@tauri-apps/plugin-clipboard-manager';

export async function copyProxyConfig(text: string) {
  await writeText(text);
  console.log('Config copied to system clipboard');
}

export async function getClipboardContent(): Promise<string> {
  return await readText();
}

```

For more complex integrations like the auto-updater, reference [`frontend/nyanpasu/src/hooks/use-updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/hooks/use-updater.ts), which demonstrates async plugin initialization and event handling:

```typescript
import { check } from '@tauri-apps/plugin-updater';

export async function checkForUpdates() {
  const update = await check();
  if (update) {
    console.log(`New version available: ${update.version}`);
  }
}

```

## Key Files for Plugin Development

When extending Clash Nyanpasu, these files define the plugin boundary between Rust and TypeScript:

- **[`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml)**: Declares Rust plugin crates and versions.
- **[`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs)**: Registers plugins via `.plugin()` calls in the Tauri builder.
- **[`backend/tauri/tauri.conf.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/tauri.conf.json)**: Stores plugin-specific JSON configurations.
- **[`frontend/nyanpasu/package.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/package.json)**: Lists JavaScript SDK dependencies like `@tauri-apps/plugin-*`.
- **[`frontend/nyanpasu/src/utils/notification.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/utils/notification.ts)**: Reference implementation showing plugin consumption patterns.
- **[`frontend/nyanpasu/src/hooks/use-updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/hooks/use-updater.ts)**: Advanced example of stateful plugin integration.

## Summary

- **Add the Rust crate** to [`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml) using the `tauri-plugin-*` naming convention.
- **Register the plugin** in [`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs) by chaining `.plugin(init_plugin())` to the Tauri builder.
- **Configure options** in [`backend/tauri/tauri.conf.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/tauri.conf.json) if the plugin requires runtime parameters.
- **Install the TypeScript SDK** via `pnpm add -D @tauri-apps/plugin-<name>` to access frontend APIs.
- **Import and await** plugin methods in React components or utility files, following the async patterns in [`notification.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/notification.ts).

## Frequently Asked Questions

### How do I add a custom Tauri plugin that isn't in the official registry?

You can add a custom plugin by creating a local Rust crate in the `backend/` directory and importing it via a path dependency in [`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml) (e.g., `tauri-plugin-custom = { path = "../tauri-plugin-custom" }`). Register it in [`main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/main.rs) using the same `.plugin()` pattern, then expose TypeScript bindings through the plugin's generated JavaScript API.

### Where does Clash Nyanpasu initialize its existing plugins?

The initialization occurs in [`backend/tauri/src/main.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/main.rs), where the Tauri application builder chains multiple `.plugin()` calls. This file constructs the application context and mounts plugins like `tauri-plugin-shell`, `tauri-plugin-process`, and `tauri-plugin-global-shortcut` before calling `.run()`.

### Can I use Tauri plugins in the frontend without installing the JavaScript SDK?

While some core Tauri APIs are available through `@tauri-apps/api`, most plugins require their specific SDK package (e.g., `@tauri-apps/plugin-clipboard-manager`) to access type-safe methods. The repository uses dedicated SDKs for all plugin interactions, as seen in [`frontend/nyanpasu/src/utils/notification.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/utils/notification.ts).

### What version of Tauri plugins does Clash Nyanpasu use?

According to [`backend/tauri/Cargo.toml`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/Cargo.toml) (lines 200-209), the project currently uses version `2.2` for most official plugins (e.g., `tauri-plugin-os = "2.2"`), with some exceptions like `tauri-plugin-opener` at `2.5`. Always match these versions when adding new plugins to ensure compatibility with the Tauri runtime.