# How Clash Nyanpasu Integrates with Different Clash Cores: Clash Premium, Mihomo, and Clash Rust

> Learn how Clash Nyanpasu seamlessly integrates with Clash Premium Mihomo and Clash Rust using its Rust Core Manager and Tauri IPC commands for effortless core switching.

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

---

**Clash Nyanpasu uses a Rust-based Core Manager that maps user-selected core identifiers to specific binaries, enabling seamless switching between Clash Premium, Mihomo, and Clash Rust through Tauri IPC commands.**

Clash Nyanpasu is a cross-platform GUI application that serves as a graphical front-end for multiple Clash proxy implementations. Understanding how Clash Nyanpasu integrates with different Clash cores reveals a sophisticated three-layer architecture that separates configuration state, process management, and frontend interactions while supporting Clash Premium, Mihomo (and its Alpha variant), and Clash Rust (plus its Alpha variant).

## Core Architecture Overview

The integration follows a strict separation of concerns across three layers:

1. **Configuration & State (Rust)** – A single `ClashCore` enum records which core the user wants to run
2. **Core Manager (Rust)** – Resolves the binary path, launches the core process, and handles hot-swapping
3. **Frontend UI & IPC (TypeScript)** – Lets the user pick a core, fetches version info, and triggers changes via Tauri IPC

## Configuration and State Management in Rust

### The ClashCore Enum

In [`backend/tauri/src/config/nyanpasu/mod.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/config/nyanpasu/mod.rs), the supported cores are defined as a Rust enum:

```rust
pub enum ClashCore {
    ClashPremium,
    ClashRs,
    Mihomo,
    MihomoAlpha,
    ClashRsAlpha,
}

```

This enum maps to the following binary names:

- **Clash Premium**: `clash`
- **Mihomo**: `mihomo`
- **Mihomo Alpha**: `mihomo-alpha`
- **Clash Rust**: `clash-rs`
- **Clash Rust Alpha**: `clash-rs-alpha`

### Persistence and Defaults

The `ClashCore` enum integrates with the global configuration through `Config::verge().data().clash_core`. When no core is selected, the system defaults to `ClashCore::ClashPremium`. The implementation provides `From<ClashCore> for String` and `From<&ClashCore> for nyanpasu_utils::core::CoreType` conversions to map the enum to binary filenames and generic core types used by the manager utilities.

## Core Manager Implementation

### Binary Resolution and Process Management

The [`backend/tauri/src/core/clash/core.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/clash/core.rs) file contains the `CoreManager` implementation that handles the lifecycle of Clash processes:

1. **Determine active core**: Reads the chosen core from configuration with fallback to `ClashPremium`
2. **Map to generic type**: Converts to `nyanpasu_utils::core::CoreType` for abstraction
3. **Find binary**: Calls `find_binary_path(&clash_core)` to locate the executable in `$APPDIR/cores`
4. **Start/restart**: Uses `CoreInstance::check_config_()` to validate configuration before spawning the process

### Hot-Swapping Cores at Runtime

The manager supports changing cores without restarting the application:

```rust
pub async fn change_core(&self, clash_core: Option<ClashCore>) -> Result<()> {
    // Persists the new core in config and restarts the core process
}

```

This method updates the configuration storage and triggers a restart of the core process with the new binary, enabling seamless switching between Clash Premium, Mihomo, and Clash Rust implementations.

### Version Resolution

In [`backend/tauri/src/utils/resolve.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/utils/resolve.rs), the `resolve_core_version` function executes `<binary> -V` to obtain version strings for any supported core, allowing the UI to display version information regardless of which implementation is active.

## Frontend Integration and IPC

### State Management with Jotai

The frontend uses Jotai for reactive state management. In [`frontend/nyanpasu/src/store/clash.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/store/clash.ts):

```typescript
export const coreTypeAtom = atom<NonNullable<VergeConfig['clash_core']>>('mihomo')

```

This atom holds the core identifier (`'clash' | 'mihomo' | 'clash-rs' | …`) and synchronizes the UI with the backend state.

### TypeScript Service Layer

The [`frontend/interface/src/service/core.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/core.ts) file provides a typed interface to the Tauri IPC layer:

```typescript
export const VALID_CORE = [
  { name: 'Clash Premium', core: 'clash' },
  { name: 'Mihomo', core: 'mihomo' },
  { name: 'Mihomo Alpha', core: 'mihomo-alpha' },
  { name: 'Clash Rust', core: 'clash-rs' },
  { name: 'Clash Rust Alpha', core: 'clash-rs-alpha' },
]

export async function getCoreVersion(core: ClashCore): Promise<string> {
  return await commands.getCoreVersion(core)
}

```

### Available IPC Commands

The backend exposes specific commands in [`backend/tauri/src/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/ipc.rs) that bridge frontend actions to the Core Manager:

- **`change_clash_core`**: Switches to another core (hot-swap)
- **`update_core`**: Downloads the latest binary for the selected core
- **`get_core_version`**: Retrieves the version string via `binary -V`
- **`fetch_latest_core_versions`**: Queries GitHub releases for available updates
- **`get_core_dir` / `open_core_dir`**: Manages the core binary storage location

## Practical Implementation Examples

### Switching Between Cores

To switch from Mihomo to Clash Rust in the frontend:

```typescript
import { changeClashCore } from '@/service/core';
import { coreTypeAtom } from '@/store/clash';
import { useAtom } from 'jotai';

const [core, setCore] = useAtom(coreTypeAtom);

async function switchToRust() {
  await changeClashCore('clash-rs');   // invokes Tauri IPC
  setCore('clash-rs');                // update UI state
}

```

Under the hood, `changeClashCore` calls Tauri's `invoke('change_clash_core', { clashCore })`, which executes `CoreManager::change_core` in Rust, updates the configuration, and restarts the core process with the `clash-rs` binary.

### Retrieving Core Versions

```typescript
import { getCoreVersion } from '@/service/core';
import { coreTypeAtom } from '@/store/clash';
import { useAtom } from 'jotai';

const [core] = useAtom(coreTypeAtom);

async function showVersion() {
  const version = await getCoreVersion(core);
  console.log(`Running ${core} version ${version}`);
}

```

This invokes `resolve_core_version` in [`backend/tauri/src/utils/resolve.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/utils/resolve.rs), which executes `<binary> -V` and returns the version string.

### Updating Core Binaries

```typescript
import { updateCore } from '@/service/core';
import { coreTypeAtom } from '@/store/clash';
import { useAtom } from 'jotai';

const [core] = useAtom(coreTypeAtom);

async function update() {
  const updatedBytes = await updateCore(core);
  console.log(`${core} updated, new size: ${updatedBytes} bytes`);
}

```

The IPC `update_core` triggers the Rust updater in [`backend/tauri/src/core/updater/mod.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/updater/mod.rs), which queries the GitHub releases API for the newest version, downloads the appropriate asset for the current OS/architecture, and replaces the binary in the core directory.

## Summary

- **Clash Nyanpasu** supports five distinct core variants: Clash Premium, Mihomo, Mihomo Alpha, Clash Rust, and Clash Rust Alpha.
- The integration relies on a Rust `ClashCore` enum in [`backend/tauri/src/config/nyanpasu/mod.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/config/nyanpasu/mod.rs) to type-safely represent the selected implementation.
- The **Core Manager** in [`backend/tauri/src/core/clash/core.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/clash/core.rs) handles binary resolution, process lifecycle, and hot-swapping between cores without application restart.
- **Tauri IPC commands** in [`backend/tauri/src/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/ipc.rs) expose core operations to the TypeScript frontend, including `change_clash_core`, `update_core`, and `get_core_version`.
- The frontend uses **Jotai atoms** in [`frontend/nyanpasu/src/store/clash.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/nyanpasu/src/store/clash.ts) for reactive state management and provides typed service wrappers in [`frontend/interface/src/service/core.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/core.ts).

## Frequently Asked Questions

### How does Clash Nyanpasu determine which core binary to execute?

Clash Nyanpasu reads the active core from the configuration using `Config::verge().latest().clash_core`, which returns a `ClashCore` enum variant. The Core Manager in [`backend/tauri/src/core/clash/core.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/clash/core.rs) converts this to a `CoreType` and calls `find_binary_path()` to locate the executable in the application-specific cores directory (typically `$APPDIR/cores`).

### Can I switch between Clash Premium and Mihomo without restarting the application?

Yes. The `change_core` method in [`backend/tauri/src/core/clash/core.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/clash/core.rs) supports hot-swapping. When you trigger a core change via the frontend (using `changeClashCore` in [`frontend/interface/src/service/core.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/core.ts)), the backend persists the new selection to the configuration file, terminates the current core process, and spawns the new binary—all without requiring an application restart.

### How does the frontend display version information for different cores?

The frontend calls `getCoreVersion` from [`frontend/interface/src/service/core.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/core.ts), which invokes the Tauri command `get_core_version` defined in [`backend/tauri/src/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/ipc.rs). The backend executes `<binary> -V` via the `resolve_core_version` function in [`backend/tauri/src/utils/resolve.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/utils/resolve.rs) and returns the version string to the UI, allowing the application to display accurate version data regardless of which core is active.

### Where are the core binaries stored and how are they updated?

Core binaries reside in a dedicated directory accessed via `get_core_dir` and `open_core_dir` IPC commands. When you initiate an update through `updateCore` in the frontend, the backend's updater module ([`backend/tauri/src/core/updater/mod.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/updater/mod.rs)) queries the GitHub releases API for the latest version of the selected core, downloads the appropriate asset for your operating system and architecture, and atomically replaces the existing binary in the cores directory.