# Managing Profiles in Clash Nyanpasu: Create, Update, Delete, and Import Guide

> Easily manage profiles in Clash Nyanpasu. Learn to create, update, delete, and import configurations with this comprehensive guide for your proxy settings.

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

---

**Managing profiles in Clash Nyanpasu involves TypeScript wrappers that invoke Rust backend commands through Tauri's IPC layer to create, update, delete, and import YAML, JavaScript, or Lua configuration files.**

Managing profiles in Clash Nyanpasu is orchestrated through a multi-layered architecture that connects the React frontend to the Rust backend via Tauri commands. The `libnyanpasu/clash-nyanpasu` repository implements this workflow through the `@nyanpasu/interface` package, which exposes type-safe hooks and service functions that ultimately invoke native commands defined in [`src-tauri/src/commands/profile.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/src-tauri/src/commands/profile.rs).

## Architecture of Profile Management in Clash Nyanpasu

The profile management system spans four distinct layers, each with specific responsibilities for handling Clash configuration files.

### Frontend UI Layer

The user interface components display profile lists and handle import dialogs. Key implementation files include:

- `frontend/nyanpasu/src/pages/(main)/main/profiles/_modules/profiles-navigate.tsx` – Renders the profile navigation and counts
- `frontend/nyanpasu/src/pages/(main)/main/profiles/_modules/profile-quick-import.tsx` – Handles the quick import dialog for remote URLs

### React Hooks and State Management

The `useProfile` hook, exported from `@nyanpasu/interface`, maintains the profile collection in a TanStack Router query cache. This hook automatically invalidates and refreshes when mutations occur.

### Tauri IPC Bridge

TypeScript wrappers in [`frontend/interface/src/service/tauri.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/tauri.ts) provide thin abstractions over native Tauri commands, while [`frontend/interface/src/ipc/bindings.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/ipc/bindings.ts) implements the low-level `TAURI_INVOKE` helpers. These layers handle serialization and type safety before invoking the Rust backend.

### Rust Backend Implementation

The actual file operations occur in [`src-tauri/src/commands/profile.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/src-tauri/src/commands/profile.rs), which implements commands for creating, updating, deleting, and importing profiles while managing the `profiles/` directory and runtime configuration.

## Profile Management API Commands

The TypeScript service layer exposes specific functions for managing profiles in Clash Nyanpasu through the Tauri command interface.

### Creating New Profiles

The `createProfile` function initializes a new profile entry and optionally writes initial file data.

```typescript
export const createProfile = async (item, fileData?) => 
  invoke<void>('create_profile', { item, fileData })

```

The `item` parameter accepts a partial `Profile` object containing fields like `type`, `name`, and `uid`. The optional `fileData` parameter holds raw content for script-type profiles (JavaScript or Lua).

### Updating Existing Profiles

Two functions handle modifications to existing profiles:

- `updateProfile` – Full updates with optional remote import options
- `patchProfile` – Partial updates modifying only specified fields

```typescript
export const updateProfile = async (uid, option?) => 
  invoke<void>('update_profile', { uid, option })

async patchProfile(uid, profile) // Partial update implementation

```

The `option` parameter uses `RemoteProfileOptionsBuilder` for configuring merge behavior during remote updates.

### Deleting Profiles

The `deleteProfile` function removes a profile from the internal store and deletes its associated file from disk.

```typescript
export const deleteProfile = async (uid) => 
  invoke<void>('delete_profile', { uid })

```

### Importing Remote Profiles

The `importProfile` function downloads configuration files from remote URLs and integrates them into the local profile collection.

```typescript
export const importProfile = async (url, option) => 
  invoke<void>('import_profile', { url, option })

```

The `option` parameter supports specifying merge behavior and script types (JavaScript or Lua) for non-YAML configurations.

### Reordering Profiles

Two functions manage profile ordering for drag-and-drop interfaces:

```typescript
reorderProfile(activeId, overId)      // Swap two specific profiles
reorderProfilesByList(list)           // Apply a complete ordering

```

## Implementation Examples for Managing Profiles

The following example demonstrates the complete workflow for managing profiles in Clash Nyanpasu using the TypeScript API:

```typescript
import {
  createProfile,
  updateProfile,
  deleteProfile,
  importProfile,
} from '@nyanpasu/interface';

// ------------------------------------------------
// 1. Create a brand-new static profile
// ------------------------------------------------
await createProfile(
  {
    uid: 'my-static-profile',
    type: 'Profile',          // plain YAML profile
    name: 'My Static Profile',
    // other fields like 'proxy' or 'rules' can be added here
  },
  null                       // no extra script data
);

// ------------------------------------------------
// 2. Update the name of an existing profile
// ------------------------------------------------
await updateProfile('my-static-profile', {
  name: 'Renamed Profile',
});

// ------------------------------------------------
// 3. Delete a profile (removes the file from disk)
// ------------------------------------------------
await deleteProfile('my-static-profile');

// ------------------------------------------------
// 4. Import a remote profile (URL can be a raw YAML or a script)
// ------------------------------------------------
await importProfile('https://raw.githubusercontent.com/example/proxy.yaml', {
  // RemoteProfileOptionsBuilder – optional flags
  merge: false,               // treat as a separate profile
  script_type: 'JavaScript', // only needed for script-type imports
});

```

All calls return a **Promise** that resolves when the native command finishes. Errors are thrown as JavaScript `Error` objects and can be caught with `try / catch`.

## UI Integration and React Hooks

The frontend components consume profile data through reactive patterns that automatically synchronize with backend state.

### Profile Navigation Component

The [`profiles-navigate.tsx`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/profiles-navigate.tsx) module displays profile counts and handles navigation:

```tsx
// File: frontend/nyanpasu/src/pages/(main)/main/profiles/_modules/profiles-navigate.tsx
import { useProfile } from '@nyanpasu/interface';
...
const { query: { data: profiles } } = useProfile();   // ← reads cache
...
// Profile counts are calculated with lodash `mapValues` and displayed

```

When Tauri commands invalidate the query cache, the hook automatically triggers a re-fetch, updating the UI with the latest profile list.

### Quick Import Dialog

The quick import interface demonstrates direct API usage:

```tsx
// File: frontend/nyanpasu/src/pages/(main)/main/profiles/_modules/profile-quick-import.tsx
import { importProfile } from '@nyanpasu/interface';
...
await importProfile(importUrl, { merge: false });

```

Upon successful import, the UI displays a confirmation toast and the `useProfile` hook refreshes the list to include the newly imported configuration.

## Rust Backend Implementation

The TypeScript wrappers ultimately invoke native commands defined in [`src-tauri/src/commands/profile.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/src-tauri/src/commands/profile.rs):

```rust
#[tauri::command]
async fn create_profile(item: ProfileBuilder, file_data: Option<String>) -> Result<(), String> { … }

#[tauri::command]
async fn update_profile(uid: String, option: Option<RemoteProfileOptionsBuilder>) -> Result<(), String> { … }

#[tauri::command]
async fn delete_profile(uid: String) -> Result<(), String> { … }

#[tauri::command]
async fn import_profile(url: String, option: Option<RemoteProfileOptionsBuilder>) -> Result<(), String> { … }

```

These functions interact with the **ProfileStore** abstraction, which manages the local `profiles/` directory. The backend handles file I/O for YAML, JavaScript, and Lua configurations, validates syntax, and notifies the runtime engine to reload the Clash configuration.

## Summary

Managing profiles in Clash Nyanpasu follows a structured flow from the React frontend through Tauri IPC to the Rust backend:

- **Frontend Components** in [`profiles-navigate.tsx`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/profiles-navigate.tsx) and [`profile-quick-import.tsx`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/profile-quick-import.tsx) provide the user interface for profile operations
- **TypeScript API** in [`frontend/interface/src/service/tauri.ts`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/frontend/interface/src/service/tauri.ts) exposes type-safe wrappers including `createProfile`, `updateProfile`, `deleteProfile`, and `importProfile`
- **React Hooks** like `useProfile` automatically synchronize UI state with backend changes through TanStack Router query invalidation
- **Rust Commands** in [`src-tauri/src/commands/profile.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/src-tauri/src/commands/profile.rs) handle the actual file system operations, validation, and runtime configuration updates

This architecture ensures that managing profiles in Clash Nyanpasu remains type-safe, reactive, and consistent across the entire application stack.

## Frequently Asked Questions

### How do I create a new profile programmatically in Clash Nyanpasu?

To create a new profile programmatically, import the `createProfile` function from `@nyanpasu/interface` and invoke it with a profile configuration object containing at minimum the `uid`, `type`, and `name` fields. For script-based profiles, provide the raw file content as the second argument. The function returns a Promise that resolves when the Rust backend has written the file to the `profiles/` directory.

### What is the difference between updateProfile and patchProfile in the Clash Nyanpasu API?

The `updateProfile` function performs a full update operation and accepts an optional `RemoteProfileOptionsBuilder` for configuring merge behavior during remote imports, making it suitable for comprehensive profile modifications. In contrast, `patchProfile` performs a partial update where only the fields explicitly provided in the profile object are modified, leaving all other existing fields unchanged. Both functions ultimately invoke commands in [`src-tauri/src/commands/profile.rs`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/src-tauri/src/commands/profile.rs) to persist changes.

### How does the useProfile hook handle real-time updates when profiles are modified?

The `useProfile` hook utilizes TanStack Router's query caching mechanism to maintain the profile list in the frontend, automatically fetching fresh data from the Rust backend when the component mounts. When mutation commands like `createProfile` or `deleteProfile` complete successfully, they trigger cache invalidation, causing the hook to re-fetch the updated profile list and re-render dependent UI components such as [`profiles-navigate.tsx`](https://github.com/libnyanpasu/clash-nyanpasu/blob/main/profiles-navigate.tsx). This reactive pattern ensures the UI remains synchronized with the filesystem state without manual refresh operations.

### Can I import profiles from remote URLs that contain JavaScript or Lua scripts instead of YAML?

Yes, the `importProfile` function supports importing remote configurations in YAML, JavaScript, or Lua formats by specifying the appropriate `script_type` in the `RemoteProfileOptionsBuilder` options parameter. When importing a script-type profile, set `script_type` to `'JavaScript'` or `'Lua'` and the Rust backend will handle the file extension and validation accordingly. The `merge` option controls whether the imported profile replaces existing configurations or merges with them, providing flexibility for complex setup scenarios.