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

TLDR: You can extend Clash Nyanpasu by registering Tauri plugins in the Rust backend (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. The Cargo.toml file at 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 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 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, matching the version used by other plugins (typically 2.2):

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

Register the Plugin in Rust

Open backend/tauri/src/main.rs and initialize the plugin within the Tauri builder chain:

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 under the "plugins" object:

{
  "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:

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, implement clipboard operations:

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, which demonstrates async plugin initialization and event handling:

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:

Summary

  • Add the Rust crate to backend/tauri/Cargo.toml using the tauri-plugin-* naming convention.
  • Register the plugin in backend/tauri/src/main.rs by chaining .plugin(init_plugin()) to the Tauri builder.
  • Configure options in 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.

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 (e.g., tauri-plugin-custom = { path = "../tauri-plugin-custom" }). Register it in 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, 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.

What version of Tauri plugins does Clash Nyanpasu use?

According to 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →