Clash Verge Developer Docs
How the interface, the Tauri layer, and Mihomo divide the work, what you need locally, how to build, and what to check before opening a pull request.
Clash Verge Frontend, Tauri Layer and Mihomo Core
Clash Verge is a Tauri 2 desktop application with separate frontend, desktop integration and proxy-core layers. React and TypeScript implement the interface, Rust and Tauri provide desktop and operating-system integration, while Mihomo handles configuration parsing, DNS, routing rules, proxy groups and traffic forwarding. Debugging should identify whether a problem belongs to the interface, desktop application layer or Mihomo core.
| Layer | Technology | Responsibilities |
|---|---|---|
| Interface layer | React + TypeScript + Vite | Profile, node, proxy-group, rule, connection and log presentation and interaction |
| Application layer | Tauri 2 + Rust | Window and tray handling, Mihomo process control, system proxy, TUN, config read/write and desktop integration |
| Core layer | Mihomo (Clash Meta) | Configuration parsing, protocol handling, DNS, rule matching, proxy groups, traffic forwarding and external-controller API |
Note A UI symptom does not necessarily indicate a frontend fault. Trace the feature through the React interface, Tauri / Rust application layer and Mihomo core before locating the issue. System integration and privileged operations belong to the desktop layer; proxy and routing behavior belong to Mihomo.
Clash Verge Local Development Dependencies
Local development requires Node.js, Corepack / pnpm, a Rust toolchain and the operating-system dependencies required by Tauri. Windows, macOS and Linux need different system-level tools.
| System | What to install | Notes |
|---|---|---|
| All platforms | Node.js, Corepack/pnpm and a Rust toolchain | Enable Corepack, then confirm node, pnpm and cargo are available |
| Windows | MSVC Rust toolchain and GNU patch; Windows ARM also needs LLVM/clang | Make sure Rust and Node.js are on PATH; Windows ARM needs clang because of native dependencies |
| macOS | Xcode Command Line Tools | xcode-select --install |
| Linux | WebKitGTK 4.1, Ayatana AppIndicator, librsvg, patchelf and related build packages | Dependency names differ by distribution; compare the current Tauri requirements with your Linux package manager |
Caution
The current contribution guide lists Ubuntu packages such as libwebkit2gtk-4.1-dev,
libayatana-appindicator3-dev, librsvg2-dev and patchelf. Other distributions use different package names, so follow the error and your platform's Tauri requirements.
Clash Verge prebuild, dev and build Commands
The local sequence installs JavaScript dependencies, prepares Mihomo and related runtime resources with prebuild, then starts development mode or produces a platform build.
-
Clone the repository
Get the source and change into the project directory.
-
Install Project Dependencies
Enable Corepack and use the repository's pnpm setup so the lockfile and dependency state match the project.
-
Prepare Mihomo and Runtime Assets
Run prebuild to prepare the Mihomo core and service / sidecar resources required by the current platform.
-
Start Development Mode
pnpm devis the standard development command. The repository also exposespnpm dev:diffandpnpm dev:taurifor specific development cases. -
Generate a Platform Build
Use
pnpm buildfor the standard Tauri build orpnpm build:fastfor a faster local test build. Output paths depend on the active target and Tauri bundle configuration.
# 1. Clone the repository
git clone https://github.com/clash-verge-rev/clash-verge-rev.git
cd clash-verge-rev
# 2. Enable Corepack and install dependencies
corepack enable
pnpm install
# 3. Download Mihomo and service binaries
pnpm run prebuild
# Re-download and overwrite them when needed:
# pnpm run prebuild --force
# 4. Start development
pnpm dev
# Alternatives:
# pnpm dev:diff
# pnpm dev:tauri
# 5. Build the current platform
pnpm build
# Faster test build:
# pnpm build:fast
Note
The dev branch currently defines prebuild, dev, dev:diff, dev:tauri,
build and build:fast in package.json. Check that file again when working against a different commit or release branch.
Clash Verge src, src-tauri and Build Scripts
The repository separates the React frontend from the Tauri / Rust application layer, with build scripts and CI configuration around them. Use the current tree to locate the real implementation before changing code.
clash-verge-rev/
├─ src/ # React + TypeScript frontend
├─ src-tauri/ # Tauri 2 + Rust desktop application
│ ├─ src/ # Rust application and system integration
│ ├─ resources/ # Runtime resources
│ ├─ sidecar/ # Mihomo and related sidecar binaries
│ ├─ Cargo.toml # Rust dependencies
│ └─ tauri.conf.json # Tauri app and bundle configuration
├─ scripts/ # Prebuild, release and development scripts
├─ .github/ # CI and GitHub Actions
├─ package.json # pnpm scripts and frontend dependencies
├─ CONTRIBUTING.md # Current development and contribution process
└─ UPDATELOG.md # Project update log
Note
This is an orientation map rather than a frozen contract. The current i18n process uses locale folders under src/locales/<lang>/
for frontend strings and separate backend locale files, so follow CONTRIBUTING_i18n.md when a change affects translated copy.
Clash Verge Tauri invoke and event IPC
Clash Verge uses Tauri APIs to connect the React frontend with the Rust application layer. Frontend code can call registered Rust commands with
invoke, while longer-lived state changes can be delivered through Tauri events. Command and event names should be traced from the current source tree.
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
// Example only: use command and event names from the current source tree
const result = await invoke("command_name", {
payload: { key: "value" },
});
const unlisten = await listen("event-name", (event) => {
console.log(event.payload);
});
// Stop listening when the component or view is disposed
unlisten();
// Example only: expose a Rust function as a Tauri command
#[tauri::command]
fn command_name(payload: serde_json::Value) -> Result<serde_json::Value, String> {
Ok(payload)
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![command_name])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Caution These snippets explain the Tauri IPC model, not the current Clash Verge command registry. Trace the frontend call site to the corresponding Rust command, event and data type before implementing or documenting a feature.
Mihomo external-controller API
Mihomo can expose control endpoints through external-controller. Clash Verge uses core APIs to inspect and modify runtime state,
while external tools can query configs, proxies, connections, rules, logs and traffic when the controller is enabled and authenticated.
# Example only: replace with the controller address used by your running profile
BASE=http://127.0.0.1:9090
AUTH="Authorization: Bearer your-secret"
# Version and current runtime config
curl -H "$AUTH" "$BASE/version"
curl -H "$AUTH" "$BASE/configs"
# Change runtime mode: rule / global / direct
curl -X PATCH -H "$AUTH" -d '{"mode":"rule"}' "$BASE/configs"
# Proxy groups and active connections
curl -H "$AUTH" "$BASE/proxies"
curl -H "$AUTH" "$BASE/connections"
# Live traffic and logs can also be consumed over WebSocket
# ws://127.0.0.1:9090/traffic?token=your-secret
# ws://127.0.0.1:9090/logs?level=info&token=your-secret
| Endpoint | Method | Purpose |
|---|---|---|
/version |
GET | Core version; commonly used to check whether the API is reachable |
/configs |
GET / PATCH / PUT | Read the config, patch parts of it (mode, ports), or reload the whole config file |
/proxies |
GET | List all nodes and proxy groups along with the current selection |
/proxies/{name} |
GET / PUT | Inspect a single node, or switch the selected node for a proxy group |
/proxies/{name}/delay |
GET | Returns latency for a given test URL and timeout |
/rules |
GET | The rules currently in effect, useful for confirming that rules loaded as expected |
/connections |
GET / DELETE | List active connections, or close a specific one |
/traffic, /logs |
WebSocket | Live upload/download traffic and the log stream |
Caution
Treat the controller URL and secret as runtime configuration rather than fixed values from an example.
An exposed controller can change proxy behavior and inspect runtime state, so bind it conservatively and protect it with authentication when appropriate.
Clash Verge Local Data, Profiles and Logs
Client settings, downloaded profiles, generated configs, scripts and logs are stored locally. These files are relevant when debugging startup, migration, profile generation or service problems.
| System | Approximate location | What's inside |
|---|---|---|
| Windows | %APPDATA%\<app identifier>\ |
Client settings, profiles and generated configs, Extension Config/Script files, Mihomo and application logs |
| macOS | ~/Library/Application Support/<app identifier>/ |
|
| Linux | ~/.local/share/<app identifier>/ |
Note Paths and application identifiers can differ by platform or build channel. Prefer the client's own app-directory and log-directory shortcuts when available, and back up important data before testing migrations or manual file edits.
Clash Verge Code Contributions and Local Checks
The contribution process focuses on a defined issue, a narrow code change, reproducible verification and the required frontend and Rust checks before review.
-
Define the Change Scope
Keep each change focused on one problem or feature area. Avoid mixing unrelated refactors, formatting changes or dependency updates into the same pull request.
-
Fork and create a branch
One branch, one thing, with a name that states the intent — for example
fix/tray-menu-crash. -
Run the Required Checks
Run
cargo clippy-allfor Rust,pnpm lintfor the frontend, then format withcargo fmtandpnpm format. Also reproduce the reported behavior and verify the actual fix. -
Keep Commits Focused
Keep commit messages and diffs focused enough that reviewers can connect each changed area to the problem being addressed. Follow the repository's current signing requirements.
-
Explain Verification in the Pull Request
Describe the problem in your own words, show how you reproduced and verified it, and include screenshots when UI behavior changes. Include the verification details required by the current contribution guidance in the pull request body.
Caution The repository applies its current contribution requirements to commit signing, scope and verification. GPL-3.0 licensing still applies, and new dependencies should have a clear technical reason and a compatible license.
Clash Verge Releases, AutoBuilds and Local Builds
Versioned releases and AutoBuilds are client build channels, while Mihomo Stable / Alpha belongs to the proxy-core layer. These version channels should be tracked separately.
| Channel | Purpose | Notes |
|---|---|---|
| Stable Release | Versioned release and archival | Versioned application releases with release notes and release assets |
| AutoBuild | Validation of newer development commits | Development builds produced from newer commits; behavior can differ from a tagged release |
| Self-built | Local development and customization | Local output depends on your build target, signing configuration and platform setup |
Note Application release channels and Mihomo core channels are different layers. A Clash Verge AutoBuild is not the same thing as switching the bundled Mihomo core to its Alpha channel. A locally built binary should be identified by its source commit, build settings and signing state.
Clash Verge Local Build and Runtime Troubleshooting
Local build and development failures usually involve dependencies, platform toolchains, missing prebuild resources or runtime WebView / system libraries. Start with the exact error and the step that produced it.
| Symptom | Common cause | What to do |
|---|---|---|
| Dependency install reports a lockfile error | Project dependencies were installed with a different package-manager state | Enable Corepack, remove the conflicting install state if necessary, then run pnpm install |
| Dev mode exits right after starting | The runtime asset preparation step was skipped | Run pnpm run prebuild; use --force when you need to re-download Mihomo and service binaries |
| Rust build reports a missing linker | Platform build tools are missing (MSVC / CLT) | Install the system build tools, reopen the terminal, then build again |
| Linux reports a missing library | Development libraries such as WebKitGTK are missing | Install the matching -dev package for the library named in the error |
| Prebuild asset download times out | The development environment cannot reach the asset download endpoints | Fix terminal/network access first, then rerun the documented prebuild process |
| Packaging succeeds but the app opens blank | The frontend assets weren't built properly, or WebView2 is missing | Confirm the frontend build output exists; on Windows, install the WebView2 runtime |
| Interface strings you edited disappear after switching language | Frontend and/or backend locale bundles were not kept in sync | Follow CONTRIBUTING_i18n.md, align locale keys and run the current i18n checks for the area you changed |
Clash Verge Repository, Releases, Issues and Source References
Use the repository, contribution guide, source tree, CI files, Releases and issue tracker when implementation details depend on a specific commit or version.
Clash Verge Repository and Contribution Entry Point
Set up the current development environment, reproduce the target behavior, keep the code change focused, run the required checks and document verification in the pull request.