How to Install, Uninstall, Start, Stop, and Restart Clash Nyanpasu Service Mode

You can install, uninstall, start, stop, and restart the Clash Nyanpasu service mode using either the Settings UI or TypeScript API helpers that invoke Tauri commands to manage the system service binary.

Clash Nyanpasu can run the Clash core as a system service, which isolates the proxy from the UI process and reduces permission requirements. This guide covers the complete service lifecycle management in the libnyanpasu/clash-nyanpasu repository, from installation through removal.

Understanding the Service Architecture

The service management workflow relies on Tauri commands exposed to the frontend. When you install, uninstall, start, stop, or restart the service, the application invokes specific Rust functions that execute the bundled nyanpasu-service binary with platform-specific arguments.

On Linux, this creates a systemd user unit; on macOS, a launchd plist; and on Windows, a native Windows Service. All operations use the current user's security context and Nyanpasu data directories.

Installing the Clash Nyanpasu Service

Using the Settings UI

Navigate to Settings → System Service and click "Install Service". This triggers the SystemServiceCtrl component located at frontend/nyanpasu/src/pages/(main)/main/settings/system/_modules/system-service-ctrl.tsx, which calls the installService() helper.

Alternatively, use the System Service Switch at frontend/nyanpasu/src/pages/(main)/main/settings/system/_modules/system-service-switch.tsx, which automatically triggers installService() when enabling service mode for the first time.

Using the TypeScript API

For programmatic installation, import the service helpers from the Tauri bridge:

import { installService, statusService } from '@nyanpasu/interface';

async function setupService() {
  const currentStatus = await statusService();
  
  if (currentStatus === 'not_installed') {
    console.log('Installing service...');
    await installService();
    console.log('Service installed successfully');
  }
}

The installService() function invokes the Tauri command install_service, which routes to install_service() in backend/tauri/src/ipc.rs and ultimately executes control::install_service() in backend/tauri/src/core/service/control.rs.

Starting, Stopping, and Restarting the Service

Service Control via UI

Once installed, the System Service panel displays the current status. Click "Start", "Stop", or "Restart" to change the service state. These buttons map to the TypeScript helpers startService(), stopService(), and restartService().

Programmatic Service Control

Manage the service lifecycle programmatically using the following API:

import { 
  startService, 
  stopService, 
  restartService, 
  statusService 
} from '@nyanpasu/interface';

async function manageServiceLifecycle() {
  // Check initial status
  let status = await statusService();
  console.log(`Initial status: ${status}`);

  // Start the service if stopped
  if (status === 'stopped') {
    console.log('Starting service...');
    await startService();
  }

  // Verify running state
  status = await statusService();
  console.log(`Status after start: ${status}`); // 'running'

  // Restart when configuration changes
  console.log('Restarting service...');
  await restartService();

  // Stop the service
  console.log('Stopping service...');
  await stopService();
  
  status = await statusService();
  console.log(`Final status: ${status}`); // 'stopped'
}

Each function invokes a corresponding Tauri command (start_service, stop_service, restart_service) defined in backend/tauri/src/ipc.rs. These commands delegate to control::start_service(), control::stop_service(), and control::restart_service() in backend/tauri/src/core/service/control.rs, which execute the nyanpasu-service binary with the appropriate action argument.

Uninstalling the Clash Nyanpasu Service

To remove the system service completely, use the "Uninstall Service" button in the UI or call uninstallService() programmatically:

import { uninstallService, statusService } from '@nyanpasu/interface';

async function removeService() {
  const status = await statusService();
  
  if (status !== 'not_installed') {
    console.log('Uninstalling service...');
    await uninstallService();
    console.log('Service removed successfully');
    
    const finalStatus = await statusService();
    console.log(`Status: ${finalStatus}`); // 'not_installed'
  }
}

The uninstallService() helper triggers the Tauri command uninstall_service, which calls control::uninstall_service() in backend/tauri/src/core/service/control.rs. This stops any running service instance and removes the systemd unit, launchd plist, or Windows service registration.

Cross-Platform Implementation Details

The service management logic in backend/tauri/src/core/service/control.rs handles platform-specific service creation:

  • Linux: Creates a systemd user service unit with the correct user SID and Nyanpasu directories
  • macOS: Generates a launchd plist file for user-level service management
  • Windows: Registers a native Windows Service using the current user's security context

All operations use the bundled nyanpasu-service binary, which receives the action command (install, uninstall, start, stop, restart) and platform-specific configuration parameters.

Summary

  • Install the service using installService() or the Settings UI, which invokes control::install_service() in backend/tauri/src/core/service/control.rs
  • Start, stop, and restart operations use startService(), stopService(), and restartService(), delegating to corresponding functions in the Rust control module
  • Uninstall removes the system service completely via uninstallService(), which calls control::uninstall_service()
  • All commands execute the nyanpasu-service binary with platform-specific arguments for systemd, launchd, or Windows Service management
  • Check current status anytime using statusService(), which returns 'running', 'stopped', or 'not_installed'

Frequently Asked Questions

What is the difference between service mode and normal mode in Clash Nyanpasu?

Service mode runs the Clash core as a separate system process isolated from the UI, reducing permission requirements and allowing the proxy to continue running even when the GUI is closed. Normal mode runs the core as a child process of the application, which terminates automatically when the app exits.

Do I need administrator privileges to install the Clash Nyanpasu service?

On Windows, installing the service requires administrator privileges because it creates a system service entry in the Windows Service Control Manager. On Linux and macOS, the service runs as a user service (systemd user unit or launchd user agent), so no root privileges are required, though you need permissions to write to the appropriate user configuration directories.

Why does the service status show "not_installed" even after I clicked install?

This typically occurs when the nyanpasu-service binary fails to create the system service entry due to permission issues, missing directories, or platform-specific security restrictions. Check the application logs for errors from control::install_service() in backend/tauri/src/core/service/control.rs, and ensure you have write permissions to system service directories or are running with elevated privileges on Windows.

Can I manage the Clash Nyanpasu service using system commands instead of the UI?

Yes, because the service is a standard system service (systemd on Linux, launchd on macOS, or Windows Service), you can manage it using native tools like systemctl --user start nyanpasu-service, launchctl, or sc.exe. However, using the application's installService(), startService(), and other helpers ensures the correct binary paths, user contexts, and directory permissions are maintained according to the implementation in backend/tauri/src/core/service/control.rs.

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 →