How to Add Custom Proxy Chains Using the Enhancement System in Clash Nyanpasu

Developers can add custom proxy chains in Clash Nyanpasu by enabling the built-in enhancement engine (enable_builtin_enhanced: true) in a profile and providing a JavaScript or Lua script that uses the chain.add() API to programmatically define proxy groups and routing rules.

The enhancement system in Clash Nyanpasu allows developers to extend profile functionality without modifying the core application. By leveraging embedded JavaScript or Lua scripts, you can dynamically inject custom proxy chains—complex routing sequences that direct traffic through multiple proxy hops—directly into the generated Clash configuration.

Understanding the Enhancement System Architecture

The enhancement system operates as a preprocessing layer between the raw profile and the Clash core. When a profile with enhancements enabled is loaded, the backend executes the specified script in a sandboxed QuickJS or Lua VM, then merges the script's output into the final configuration.

Key architectural components include:

Enabling Custom Proxy Chains in Your Profile

To activate the enhancement engine for custom proxy chains, you must set enable_builtin_enhanced: true in your profile YAML and specify the path to your enhancement script.


# example-profile.yaml

name: Custom-Chain-Profile
port: 7890
socks-port: 7891
allow-lan: false
mode: rule
log-level: info

# Enable the enhancement engine

enable_builtin_enhanced: true

# Path to the script (relative to the profile directory)

script: my-chain.js

When this profile is selected in the Clash Nyanpasu UI, the backend automatically loads my-chain.js and executes it against the configuration context.

Writing Enhancement Scripts for Proxy Chains

Enhancement scripts interact with a context object exposing the chain and dns APIs. You can write these scripts in either JavaScript or Lua, depending on your preference.

JavaScript Implementation

The JavaScript runner uses QuickJS. The global chain object provides methods to construct proxy groups and routing rules.

// my-chain.js - Custom proxy chain definition
// Run by the built-in QuickJS runner in backend/tauri/src/enhance/script/js.rs

// 1. Create a "select" proxy group containing three regional proxies
chain.add('My-Proxy-Chain', 'select', [
  '🇺🇸 US-Proxy',
  '🇯🇵 JP-Proxy',
  '🇭🇰 HK-Proxy',
]);

// 2. Add a rule routing all example.com traffic through the custom chain
chain.addRule('DOMAIN-SUFFIX,example.com,My-Proxy-Chain');

// 3. (Optional) Inject a DNS-over-TLS server for this chain
dns.addServer('tls://1.1.1.1');

Lua Implementation

The Lua implementation offers identical functionality through the same API surface, processed by backend/tauri/src/enhance/script/lua/mod.rs.

-- my-chain.lua - Equivalent Lua implementation
-- Processed by backend/tauri/src/enhance/script/lua/mod.rs

-- Build the proxy group
chain.add('Fast-Chain', 'select', {
  '🇺🇸 US-Fast',
  '🇬🇧 UK-Fast',
  '🇸🇬 SG-Fast',
})

-- Route Google domains through the chain
chain.addRule('DOMAIN-KEYWORD,google,Fast-Chain')

-- Add DNS server (optional)
dns.addServer('tls://1.0.0.1')

Key API Methods for Proxy Chain Manipulation

The enhancement context exposes three primary APIs for custom proxy chains:

  • chain.add(name, type, selectors, options?) – Creates a new proxy group. The type parameter accepts standard Clash group types (select, url-test, fallback, load-balance). The selectors array lists proxy names or other groups to include.
  • chain.addRule(rule) – Appends a rule string to the global rule list. Rules follow standard Clash syntax (DOMAIN-SUFFIX, DOMAIN-KEYWORD, IP-CIDR, etc.) and must reference valid proxy groups created via chain.add().
  • dns.addServer(url) – Injects a DNS server configuration. Accepts standard DNS URLs including DoT (tls://) and DoH (https://) formats.

These methods are implemented in backend/tauri/src/enhance/chain.rs and exposed to the script runtimes through the respective binding layers.

Backend Implementation Details

The enhancement system processes custom proxy chains through a specific execution pipeline:

  1. Configuration Loading: When a profile is selected, backend/tauri/src/config/nyanpasu/mod.rs checks for enable_builtin_enhanced: true.
  2. Script Execution: The enhance() function in backend/tauri/src/enhance/mod.rs loads the script file specified in the script: field.
  3. Runtime Binding: Depending on file extension, either backend/tauri/src/enhance/script/js.rs (QuickJS) or backend/tauri/src/enhance/script/lua/mod.rs (Lua) initializes the VM and binds the chain and dns APIs.
  4. Object Merging: The script's output is collected into intermediate structures defined in backend/tauri/src/enhance/chain.rs, then merged with the base profile using utilities in backend/tauri/src/enhance/utils.rs.
  5. Core Handoff: The final merged configuration is written to disk and loaded by the Clash core.

This architecture ensures that custom proxy chains are computed dynamically while maintaining sandboxed execution of user scripts.

Frontend Integration

Users interact with the enhancement system through the React-based frontend:

When a user toggles this setting or edits a script, the frontend calls enhanceProfiles() to force the backend to re-run the enhancement pipeline and update the active custom proxy chains.

Summary

Developers can implement custom proxy chains in Clash Nyanpasu by leveraging the built-in enhancement engine:

  • Enable enhancements by setting enable_builtin_enhanced: true in the profile YAML and specifying a script: path.
  • Write JavaScript or Lua scripts that use the chain.add(), chain.addRule(), and dns.addServer() APIs to define proxy groups and routing logic.
  • The backend processes these scripts in backend/tauri/src/enhance/mod.rs using sandboxed QuickJS or Lua VMs, merging the output into the final Clash configuration.
  • The frontend provides UI controls in frontend/interface/src/components/setting/setting-nyanpasu-misc.tsx to toggle enhancements and trigger re-processing via enhanceProfiles().

This system allows dynamic, scriptable proxy chain customization without rebuilding the application or modifying core source code.

Frequently Asked Questions

What scripting languages are supported for custom proxy chains?

Clash Nyanpasu supports both JavaScript and Lua for writing enhancement scripts. JavaScript runs inside a QuickJS sandbox (backend/tauri/src/enhance/script/js.rs), while Lua uses the embedded Lua interpreter (backend/tauri/src/enhance/script/lua/mod.rs). Both languages expose identical APIs for manipulating proxy chains.

Where should I place the enhancement script file?

Place the script file in the same directory as your profile YAML file, or provide a relative path in the script: field of your profile configuration. The backend resolves the path relative to the profile location when enable_builtin_enhanced: true is set and the profile is loaded.

Can I modify existing proxy groups or only create new ones?

The enhancement API primarily focuses on creating new proxy groups via chain.add() and adding rules via chain.addRule(). While the backend merging logic in backend/tauri/src/enhance/utils.rs handles combining script output with base configuration, the provided API is designed for additive customization rather than mutating existing profile definitions.

How do I trigger re-enhancement after editing a script?

After modifying your enhancement script, trigger re-processing by calling the enhanceProfiles() IPC method available in frontend/interface/src/ipc/bindings.ts. The frontend React component setting-nyanpasu-misc.tsx provides a UI toggle for enabling enhancements, but manual re-enhancement ensures script changes are immediately applied without restarting the application.

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 →