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. TheCargo.tomlfile atbackend/tauri/Cargo.toml(lines 200-209) declares plugin dependencies liketauri-plugin-clipboard-manager = "2.2"andtauri-plugin-notification = "2.2". -
Configuration: The
backend/tauri/tauri.conf.jsonfile 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.tsdemonstrates 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:
backend/tauri/Cargo.toml: Declares Rust plugin crates and versions.backend/tauri/src/main.rs: Registers plugins via.plugin()calls in the Tauri builder.backend/tauri/tauri.conf.json: Stores plugin-specific JSON configurations.frontend/nyanpasu/package.json: Lists JavaScript SDK dependencies like@tauri-apps/plugin-*.frontend/nyanpasu/src/utils/notification.ts: Reference implementation showing plugin consumption patterns.frontend/nyanpasu/src/hooks/use-updater.ts: Advanced example of stateful plugin integration.
Summary
- Add the Rust crate to
backend/tauri/Cargo.tomlusing thetauri-plugin-*naming convention. - Register the plugin in
backend/tauri/src/main.rsby chaining.plugin(init_plugin())to the Tauri builder. - Configure options in
backend/tauri/tauri.conf.jsonif 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →