# How Clash Nyanpasu Manages System Proxy Configuration: A Deep Dive into the Cross-Platform Implementation

> Discover how Clash Nyanpasu handles system proxy configuration. Learn about its Tauri backend, OS-specific modules, and React frontend integration for seamless proxy management.

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

---

**Clash Nyanpasu manages system proxy configuration through a Tauri-based backend that reads and writes OS-specific proxy settings via platform-specific modules, exposing these capabilities to the React frontend through IPC commands.**

The `libnyanpasu/clash-nyanpasu` repository implements a robust, cross-platform system proxy management layer that bridges the React frontend with native operating system APIs. This article examines how system proxy configuration is queried, applied, and synchronized across Windows, macOS, and Linux.

## Architecture Overview of System Proxy Management

The system proxy implementation follows a three-layer architecture that separates platform-specific logic from the user interface.

### Frontend Layer (React Hooks and IPC Bindings)

The frontend exposes system proxy state through custom React hooks and Tauri command bindings. The `useSystemProxy` hook in [`frontend/interface/src/ipc/use-system-proxy.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/ipc/use-system-proxy.ts) provides reactive access to the current system proxy configuration, while [`frontend/interface/src/ipc/bindings.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/ipc/bindings.ts) defines the IPC interface mapping to Tauri commands.

### Tauri IPC Layer (Command Handlers)

The Tauri backend receives IPC calls through command handlers defined in [`backend/tauri/src/core/service/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/service/ipc.rs). These handlers act as a bridge, forwarding requests to the core system proxy module and returning structured JSON responses to the frontend.

### Core System Proxy Module (Platform-Specific Implementation)

The [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs) file contains the platform-specific logic for reading and writing system proxy settings. This module abstracts Windows registry operations, macOS `networksetup` commands, and Linux `gsettings` or environment variable manipulations behind a unified `SystemProxy` struct.

## Reading System Proxy Configuration

Querying the current system proxy state follows a unidirectional data flow from the UI to the OS APIs.

The frontend initiates the request through the `useSystemProxy` hook, which utilizes React Query to call `commands.getSysProxy()`. This method invokes the Tauri command `get_sys_proxy`, handled in [`backend/tauri/src/core/service/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/service/ipc.rs):

```rust
#[tauri::command]
pub async fn get_sys_proxy(state: State<'_, AppState>) -> Result<SystemProxy> {
    Sysopt::get().await
}

```

The `Sysopt::get()` implementation in [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs) dispatches to platform-specific readers:

- **Windows**: Reads from the registry key `HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings`
- **macOS**: Executes `networksetup -getwebproxy` and `networksetup -getsecurewebproxy`
- **Linux**: Queries `gsettings` for `org.gnome.system.proxy` or reads environment variables

The function returns a normalized `SystemProxy` struct containing `enabled`, `http`, `https`, and `bypass` fields, which the frontend receives as JSON:

```typescript
import { useSystemProxy } from '@/ipc/use-system-proxy'

export function ProxyStatus() {
  const { data, isLoading, error } = useSystemProxy()

  if (isLoading) return <p>Loading proxy…</p>
  if (error) return <p>Failed to fetch proxy</p>

  const { enabled, http, https, bypass } = data!
  return (
    <div>
      <p>System proxy: {enabled ? 'ON' : 'OFF'}</p>
      {enabled && (
        <>
          <p>HTTP: {http}</p>
          <p>HTTPS: {https}</p>
          <p>Bypass: {bypass}</p>
        </>
      )}
    </div>
  )
}

```

## Applying System Proxy Configuration

When a user toggles system proxy settings, the application writes configuration changes back to the operating system.

The process begins in the frontend when a user interaction triggers `commands.setSysProxy()`. The [`backend/tauri/src/core/manager.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/manager.rs) file monitors the `enable_system_proxy` configuration setting and invokes `Sysopt::apply()` when changes are detected:

```rust
// In backend/tauri/src/core/manager.rs
// When enable_system_proxy setting changes:
Sysopt::apply(enable, &proxy).await?;

```

The `Sysopt::apply()` method in [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs) handles platform-specific writes:

**Windows Implementation**
Writes to the Windows Registry under `HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings`, setting `ProxyEnable` (DWORD) and `ProxyServer` (String), then calls `InternetSetOption` to refresh the system proxy configuration without requiring a browser restart.

**macOS Implementation**
Uses `networksetup` command-line tool:
- `networksetup -setwebproxy <service> <host> <port>`
- `networksetup -setsecurewebproxy <service> <host> <port>`
- `networksetup -setproxybypassdomains <service> <domains>`

**Linux Implementation**
Prioritizes GNOME desktop environment via `gsettings`:
- `gsettings set org.gnome.system.proxy mode "manual"`
- `gsettings set org.gnome.system.proxy.http host <host>` and `port <port>`
- Similar settings for `https` host and port

Falls back to environment variable export for non-GNOME environments.

## Automatic Synchronization and Refresh

The frontend maintains synchronization with the system state through polling and reactive updates.

The `useSystemProxy` hook configures React Query with a `refetchInterval` of 5000 milliseconds, ensuring the UI reflects any external changes to system proxy settings within five seconds. Additionally, the hook uses `useUpdateEffect` to trigger immediate refetching when the `enable_system_proxy` setting changes internally.

This dual approach ensures that:
1. External modifications (user changing OS settings manually) are detected via polling
2. Internal toggles (user clicking the enable/disable button) trigger immediate updates via the settings observer in [`backend/tauri/src/core/manager.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/manager.rs)

## Summary

- **Three-layer architecture**: React frontend hooks → Tauri IPC commands → Platform-specific core module in [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs)
- **Cross-platform implementation**: Windows uses Registry writes with `InternetSetOption`, macOS uses `networksetup` commands, and Linux uses `gsettings` with environment variable fallback
- **Bidirectional sync**: The `useSystemProxy` hook polls every 5 seconds while [`backend/tauri/src/core/manager.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/manager.rs) watches settings to trigger immediate `Sysopt::apply()` calls
- **Normalized data model**: All platforms return a consistent `SystemProxy` struct with `enabled`, `http`, `https`, and `bypass` fields

## Frequently Asked Questions

### How does Clash Nyanpasu detect changes to system proxy settings made outside the application?

Clash Nyanpasu uses a polling mechanism in the frontend. The `useSystemProxy` hook in [`frontend/interface/src/ipc/use-system-proxy.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/ipc/use-system-proxy.ts) configures React Query with a `refetchInterval` of 5000 milliseconds, calling `commands.getSysProxy()` every five seconds to query the current OS proxy state via the Tauri backend.

### What happens when I toggle the "Enable system proxy" setting in the UI?

When you toggle the setting, the frontend calls `commands.setSysProxy()` which invokes the Tauri command handler in [`backend/tauri/src/core/service/ipc.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/service/ipc.rs). This triggers `Sysopt::apply()` in [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs), which writes the appropriate configuration to the Windows Registry, macOS network settings via `networksetup`, or Linux `gsettings` depending on your platform.

### Does Clash Nyanpasu support system proxy configuration on Linux desktop environments other than GNOME?

Yes, while the primary implementation in [`backend/tauri/src/core/sysopt.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/backend/tauri/src/core/sysopt.rs) uses `gsettings` for GNOME-based environments, the module includes fallback logic that exports environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) for non-GNOME desktop environments or headless configurations.

### Where is the system proxy state stored when the application reads it from the operating system?

The system proxy state is not stored locally by Clash Nyanpasu; it is read dynamically from the operating system's configuration. On Windows, it reads from `HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings`. On macOS, it executes `networksetup` commands. On Linux, it queries `gsettings` or environment variables. The result is normalized into a `SystemProxy` struct and returned to the frontend without persistent storage.