# Clash Nyanpasu Auto-Update Mechanism and Core Version Management: A Technical Deep Dive

> Explore the Clash Nyanpasu auto-update mechanism and how it manages multiple core versions via cryptographically signed metadata for Mihomo, Clash-RS, and Clash Premium ensuring seamless operation.

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

---

**Clash Nyanpasu implements a self-contained update pipeline that generates cryptographically signed [`update.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update.json) metadata files from GitHub releases, while centrally managing multiple proxy core versions through [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json) to enable seamless automatic updates and runtime core switching between Mihomo, Clash-RS, and Clash Premium.**

The `libnyanpasu/clash-nyanpasu` repository maintains a sophisticated auto-update mechanism that eliminates manual binary management for users across platforms. This system automatically resolves the latest releases from various upstream Clash cores, generates platform-specific metadata, and publishes version-controlled update manifests. Understanding this architecture reveals how the application handles secure, cross-platform distribution while supporting multiple proxy engine variants simultaneously.

## How the Auto-Update Pipeline Works

The update process centers on [`scripts/updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/updater.ts), which orchestrates the creation of machine-readable manifests that the UI consumes to download correct binaries for the user's operating system and CPU architecture.

### Resolving Releases and Building update.json

The `resolveUpdater()` function queries the repository's tags to identify the most recent stable release starting with `v`. It then resolves all associated binary assets and their corresponding `.sig` signature files. The script constructs a JSON object containing `name`, `notes`, `pub_date`, and a `platforms` map that associates specific OS/architecture combinations with signed download URLs.

### Proxy Acceleration and Asset Publication

To mitigate GitHub throttling in certain regions, the script generates a proxy-accelerated variant of the update manifest. The `getGithubUrl()` helper in [`scripts/utils/utils.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/utils/utils.ts) rewrites all asset URLs to route through `https://hub.fastgit.xyz/`, creating an [`update-proxy.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update-proxy.json) alongside the standard [`update.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update.json). Both files are published to a dedicated GitHub release tagged **`updater`**. If this release doesn't exist, the script creates it as a pre-release, deletes stale `update*.json` assets, and uploads fresh copies (lines 124-165 in [`updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/updater.ts)).

### Cryptographic Verification and Local Caching

Each binary asset includes a detached signature file accessed via `getSignature()`. The updater embeds these signatures into the JSON metadata, enabling the client to verify integrity before execution. For offline environments or development workflows, invoking the CLI with `--cache-path` triggers `saveToCache()` to store the generated JSON files locally, bypassing network checks on subsequent runs.

## Core Version Management Architecture

Clash Nyanpasu supports multiple proxy engines (mihomo, clash-rs, clash-premium, clash-meta) simultaneously. The versioning logic spans three architectural layers to maintain consistency across platforms.

### Central Version Registry

The file [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json) serves as the single source of truth for all supported cores. It stores semantic versions (or git hashes) under the `latest` key for each engine, alongside an `arch_template` mapping that defines per-platform binary naming conventions:

```json
{
  "latest": {
    "mihomo": "v1.19.20",
    "clash_rs": "v0.9.4",
    "clash_premium": "2023-09-05-gdcc8d87",
    "clash_rs_alpha": "0.9.4-alpha+sha.e11288b"
  },
  "arch_template": {
    "clash_rs": {
      "windows-x86_64": "clash-x86_64-pc-windows-msvc.exe",
      "darwin-arm64": "clash-aarch64-apple-darwin"
    }
  }
}

```

*Source:* [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json)

### Per-Core Manifest Abstractions

Located in `scripts/manifest/`, TypeScript files like [`clash-rs.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/clash-rs.ts), [`clash-premium.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/clash-premium.ts), and [`clash-meta.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/clash-meta.ts) expose three critical properties for the downloader: `URL_PREFIX` (the base GitHub releases URL), `VERSION` (pulled from [`version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/version.json)), and `ARCH_MAPPING` (the platform-specific filename templates). For example, the Clash-RS manifest exports:

```typescript
export const CLASH_RS_MANIFEST: ClashManifest = {
  URL_PREFIX: 'https://github.com/Watfaq/clash-rs/releases/download/',
  VERSION: versionManifest.latest.clash_rs,
  ARCH_MAPPING: versionManifest.arch_template.clash_rs,
};

```

*Source:* [`scripts/manifest/clash-rs.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/manifest/clash-rs.ts)

### Runtime URL Resolution

The [`scripts/utils/resource.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/utils/resource.ts) module handles dynamic core switching at runtime. Given a core name and the current platform identifier (e.g., `win32-x64` or `darwin-arm64`), it selects the appropriate manifest and constructs the final download URL using the pattern `${URL_PREFIX}${VERSION}/${ARCH_MAPPING[platform]}`. This enables the UI to fetch the correct binary immediately when users switch between Mihomo, Clash-RS, or Clash Premium engines.

## Nightly Build Variant

For bleeding-edge releases, [`scripts/updater-nightly.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/updater-nightly.ts) mirrors the stable pipeline but targets the **`pre-release`** tag instead of `updater`. It injects the short Git hash into the version string (e.g., `v1.2.3-alpha+abcd123`), allowing users to track specific commit builds while maintaining the same cryptographic verification and platform detection logic implemented in the stable updater.

## Typical Update Flow Implementation

When the application checks for updates, it executes the following sequence:

```typescript
// 1. Load the updater JSON from GitHub or FastGit proxy
const updaterUrl = `${githubRepoUrl}/releases/download/updater/update.json`;
const updaterInfo = await fetch(updaterUrl).then(r => r.json());

// 2. Detect current platform (win64, darwin-aarch64, etc.)
const platform = detectPlatform();

// 3. Extract download URL and signature for current arch
const { url, signature } = updaterInfo.platforms[platform];

// 4. Verify cryptographic signature
await verifySignature(url, signature);

// 5. Download and install the binary
await downloadFile(url, targetPath);

```

For manual core switches initiated through the UI settings, the application bypasses the updater JSON entirely and calls the resource resolver directly, computing the URL from [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json) and the per-core manifests in real-time.

## Summary

- **Auto-update generation**: The [`scripts/updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/updater.ts) script synthesizes [`update.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update.json) and [`update-proxy.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update-proxy.json) files containing signed binary URLs for every supported platform/architecture combination.
- **Release tagging**: Stable updates publish to the `updater` release tag, while nightly builds use `pre-release` with git-hash versioning.
- **Centralized versioning**: [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json) maintains authoritative version strings and architecture templates for all cores (mihomo, clash-rs, clash-premium).
- **Runtime resolution**: [`scripts/utils/resource.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/utils/resource.ts) constructs download URLs dynamically using per-core manifests, enabling instant switching between proxy engines.
- **Security**: Detached Ed25519 signature files (`.sig`) are embedded in update metadata and verified before execution via `getSignature()`.

## Frequently Asked Questions

### How does Clash Nyanpasu verify the integrity of auto-updates?

The updater embeds **cryptographic signatures** into the [`update.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update.json) metadata via the `getSignature()` function. Before executing any downloaded binary, the client verifies the signature against the corresponding `.sig` file fetched from the GitHub release assets, ensuring the binary hasn't been tampered with during transit or storage.

### What is the difference between stable and nightly auto-updates?

Stable releases use [`scripts/updater.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/updater.ts) and publish to the **`updater`** tag with semantic versioning (e.g., `v1.2.3`), while nightly builds use [`scripts/updater-nightly.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/updater-nightly.ts) targeting the **`pre-release`** tag. Nightly versions append the short Git hash (e.g., `v1.2.3-alpha+abcd123`) to identify specific commit builds and provide granular debugging information.

### How does Clash Nyanpasu handle slow GitHub downloads in certain regions?

The pipeline generates a proxy-accelerated manifest ([`update-proxy.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/update-proxy.json)) where all URLs are rewritten through `https://hub.fastgit.xyz/` via the `getGithubUrl()` utility. The UI automatically selects this mirror when detecting network conditions that benefit from the FastGit CDN, significantly improving download speeds in regions with GitHub throttling or connectivity issues.

### Can users switch proxy cores without waiting for an auto-update?

Yes. When users select a different core in the UI (e.g., switching from Mihomo to Clash-RS), the application bypasses the updater JSON and invokes [`scripts/utils/resource.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/scripts/utils/resource.ts) to resolve the download URL directly from [`manifest/version.json`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/manifest/version.json) and the per-core manifest files. This enables immediate downloading of the selected core version without requiring a new updater release.