diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index 4ff20db104a82f5979cfc56da27371c6579e3107..1f13a7c1beeb13d70751bf2b0f32fb0c77ef11ea 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -1,12 +1,7 @@
 use crate::{
   core::{ClashInfo, ProfileItem, ProfilesConfig, VergeConfig},
   states::{ClashState, ProfilesState, VergeState},
-  utils::{
-    config::{read_clash, save_clash},
-    dirs::app_home_dir,
-    fetch::fetch_profile,
-    sysopt::SysProxyConfig,
-  },
+  utils::{dirs::app_home_dir, fetch::fetch_profile, sysopt::SysProxyConfig},
 };
 use serde_yaml::Mapping;
 use std::process::Command;
@@ -82,7 +77,7 @@ pub async fn update_profile(
         let current = profiles.current.clone().unwrap_or(0);
         if current == index {
           let clash = clash.0.lock().unwrap();
-          profiles.activate(clash.info.clone())
+          profiles.activate(&clash)
         } else {
           Ok(())
         }
@@ -105,7 +100,7 @@ pub fn select_profile(
   match profiles.put_current(index) {
     Ok(()) => {
       let clash = clash.0.lock().unwrap();
-      profiles.activate(clash.info.clone())
+      profiles.activate(&clash)
     }
     Err(err) => Err(err),
   }
@@ -123,7 +118,7 @@ pub fn delete_profile(
     Ok(change) => match change {
       true => {
         let clash = clash_state.0.lock().unwrap();
-        profiles.activate(clash.info.clone())
+        profiles.activate(&clash)
       }
       false => Ok(()),
     },
@@ -179,18 +174,10 @@ pub fn restart_sidecar(
   profiles_state: State<'_, ProfilesState>,
 ) -> Result<(), String> {
   let mut clash = clash_state.0.lock().unwrap();
+  let mut profiles = profiles_state.0.lock().unwrap();
 
-  match clash.restart_sidecar() {
-    Ok(_) => {
-      let profiles = profiles_state.0.lock().unwrap();
-      match profiles.activate(clash.info.clone()) {
-        Ok(()) => Ok(()),
-        Err(err) => {
-          log::error!("{}", err);
-          Err(err)
-        }
-      }
-    }
+  match clash.restart_sidecar(&mut profiles) {
+    Ok(_) => Ok(()),
     Err(err) => {
       log::error!("{}", err);
       Err(err)
@@ -203,26 +190,23 @@ pub fn restart_sidecar(
 #[tauri::command]
 pub fn get_clash_info(clash_state: State<'_, ClashState>) -> Result<ClashInfo, String> {
   match clash_state.0.lock() {
-    Ok(arc) => Ok(arc.info.clone()),
+    Ok(clash) => Ok(clash.info.clone()),
     Err(_) => Err("failed to get clash lock".into()),
   }
 }
 
-/// todo: need refactor
 /// update the clash core config
 /// after putting the change to the clash core
 /// then we should save the latest config
 #[tauri::command]
-pub fn patch_clash_config(payload: Mapping) -> Result<(), String> {
-  let mut config = read_clash();
-  for (key, value) in payload.iter() {
-    if config.contains_key(key) {
-      config[key] = value.clone();
-    } else {
-      config.insert(key.clone(), value.clone());
-    }
-  }
-  save_clash(&config)
+pub fn patch_clash_config(
+  payload: Mapping,
+  clash_state: State<'_, ClashState>,
+  profiles_state: State<'_, ProfilesState>,
+) -> Result<(), String> {
+  let mut clash = clash_state.0.lock().unwrap();
+  let mut profiles = profiles_state.0.lock().unwrap();
+  clash.patch_config(payload, &mut profiles)
 }
 
 /// get the system proxy
diff --git a/src-tauri/src/core/clash.rs b/src-tauri/src/core/clash.rs
index e281b04fce89dc8edebd3aa9c601e8f9f52ca82b..e212cbdb5a157c8db3b3a54a98c178a70763551d 100644
--- a/src-tauri/src/core/clash.rs
+++ b/src-tauri/src/core/clash.rs
@@ -1,3 +1,4 @@
+use super::ProfilesConfig;
 use crate::utils::{config, dirs};
 use serde::{Deserialize, Serialize};
 use serde_yaml::{Mapping, Value};
@@ -20,6 +21,9 @@ pub struct ClashInfo {
 
 #[derive(Debug)]
 pub struct Clash {
+  /// maintain the clash config
+  pub config: Mapping,
+
   /// some info
   pub info: ClashInfo,
 
@@ -32,17 +36,19 @@ static CLASH_CONFIG: &str = "config.yaml";
 // todo: be able to change config field
 impl Clash {
   pub fn new() -> Clash {
+    let config = Clash::get_config();
+    let info = Clash::get_info(&config);
+
     Clash {
-      info: Clash::get_info(),
+      config,
+      info,
       sidecar: None,
     }
   }
 
   /// parse the clash's config.yaml
   /// get some information
-  fn get_info() -> ClashInfo {
-    let clash_config = config::read_yaml::<Mapping>(dirs::app_home_dir().join(CLASH_CONFIG));
-
+  fn get_info(clash_config: &Mapping) -> ClashInfo {
     let key_port_1 = Value::String("port".to_string());
     let key_port_2 = Value::String("mixed-port".to_string());
     let key_server = Value::String("external-controller".to_string());
@@ -93,12 +99,6 @@ impl Clash {
     }
   }
 
-  /// update the clash info
-  pub fn update_info(&mut self) -> Result<(), String> {
-    self.info = Clash::get_info();
-    Ok(())
-  }
-
   /// run clash sidecar
   pub fn run_sidecar(&mut self) -> Result<(), String> {
     let app_dir = dirs::app_home_dir();
@@ -138,10 +138,56 @@ impl Clash {
   }
 
   /// restart clash sidecar
-  pub fn restart_sidecar(&mut self) -> Result<(), String> {
-    self.update_info()?;
+  /// should reactivate profile after restart
+  pub fn restart_sidecar(&mut self, profiles: &mut ProfilesConfig) -> Result<(), String> {
+    self.update_config();
     self.drop_sidecar()?;
-    self.run_sidecar()
+    self.run_sidecar()?;
+    profiles.activate(&self)
+  }
+
+  /// update the clash info
+  pub fn update_config(&mut self) {
+    self.config = Clash::get_config();
+    self.info = Clash::get_info(&self.config);
+  }
+
+  /// get clash config
+  fn get_config() -> Mapping {
+    config::read_yaml::<Mapping>(dirs::app_home_dir().join(CLASH_CONFIG))
+  }
+
+  /// save the clash config
+  fn save_config(&self) -> Result<(), String> {
+    config::save_yaml(
+      dirs::app_home_dir().join(CLASH_CONFIG),
+      &self.config,
+      Some("# Default Config For Clash Core\n\n"),
+    )
+  }
+
+  /// patch update the clash config
+  pub fn patch_config(
+    &mut self,
+    patch: Mapping,
+    profiles: &mut ProfilesConfig,
+  ) -> Result<(), String> {
+    for (key, value) in patch.iter() {
+      let value = value.clone();
+      let key_str = key.as_str().clone().unwrap_or("");
+
+      // restart the clash
+      if key_str == "mixed-port" {
+        self.restart_sidecar(profiles)?;
+      }
+
+      if self.config.contains_key(key) {
+        self.config[key] = value.clone();
+      } else {
+        self.config.insert(key.clone(), value.clone());
+      }
+    }
+    self.save_config()
   }
 }
 
diff --git a/src-tauri/src/core/profiles.rs b/src-tauri/src/core/profiles.rs
index 1581624a3a940ee04061e90a2027fee43cefdcfa..386d6b78f430fae57d6682f9a875e384fe34d7c1 100644
--- a/src-tauri/src/core/profiles.rs
+++ b/src-tauri/src/core/profiles.rs
@@ -1,3 +1,4 @@
+use super::{Clash, ClashInfo};
 use crate::utils::{config, dirs};
 use reqwest::header::HeaderMap;
 use serde::{Deserialize, Serialize};
@@ -8,8 +9,6 @@ use std::fs::File;
 use std::io::Write;
 use std::time::{SystemTime, UNIX_EPOCH};
 
-use super::ClashInfo;
-
 /// Define the `profiles.yaml` schema
 #[derive(Default, Debug, Clone, Deserialize, Serialize)]
 pub struct ProfilesConfig {
@@ -224,7 +223,7 @@ impl ProfilesConfig {
   }
 
   /// activate current profile
-  pub fn activate(&self, clash_config: ClashInfo) -> Result<(), String> {
+  pub fn activate(&self, clash: &Clash) -> Result<(), String> {
     let current = self.current.unwrap_or(0);
     match self.items.clone() {
       Some(items) => {
@@ -233,11 +232,13 @@ impl ProfilesConfig {
         }
 
         let profile = items[current].clone();
+        let clash_config = clash.config.clone();
+        let clash_info = clash.info.clone();
         tauri::async_runtime::spawn(async move {
           let mut count = 5; // retry times
           let mut err = String::from("");
           while count > 0 {
-            match activate_profile(&profile, &clash_config).await {
+            match activate_profile(&profile, &clash_config, &clash_info).await {
               Ok(_) => return,
               Err(e) => err = e,
             }
@@ -254,7 +255,11 @@ impl ProfilesConfig {
 }
 
 /// put the profile to clash
-pub async fn activate_profile(profile_item: &ProfileItem, info: &ClashInfo) -> Result<(), String> {
+pub async fn activate_profile(
+  profile_item: &ProfileItem,
+  clash_config: &Mapping,
+  clash_info: &ClashInfo,
+) -> Result<(), String> {
   // temp profile's path
   let temp_path = temp_dir().join(PROFILE_TEMP);
 
@@ -267,25 +272,46 @@ pub async fn activate_profile(profile_item: &ProfileItem, info: &ClashInfo) -> R
 
     let file_path = dirs::app_home_dir().join("profiles").join(file_name);
     if !file_path.exists() {
-      return Err(format!("profile `{:?}` not exists", file_path));
+      return Err(format!(
+        "profile `{}` not exists",
+        file_path.as_os_str().to_str().unwrap()
+      ));
     }
 
+    // begin to generate the new profile config
+    let def_config = config::read_yaml::<Mapping>(file_path.clone());
+    let mut new_config = Mapping::new();
+
     // Only the following fields are allowed:
     // proxies/proxy-providers/proxy-groups/rule-providers/rules
-    let config = config::read_yaml::<Mapping>(file_path.clone());
-    let mut new_config = Mapping::new();
-    vec![
+    let valid_keys = vec![
       "proxies",
       "proxy-providers",
       "proxy-groups",
       "rule-providers",
       "rules",
-    ]
-    .iter()
-    .map(|item| Value::String(item.to_string()))
-    .for_each(|key| {
-      if config.contains_key(&key) {
-        let value = config[&key].clone();
+    ];
+    valid_keys.iter().for_each(|key| {
+      let key = Value::String(key.to_string());
+      if def_config.contains_key(&key) {
+        let value = def_config[&key].clone();
+        new_config.insert(key, value);
+      }
+    });
+
+    // add some of the clash `config.yaml` config to it
+    let valid_keys = vec![
+      "mixed-port",
+      "log-level",
+      "allow-lan",
+      "external-controller",
+      "secret",
+      "ipv6",
+    ];
+    valid_keys.iter().for_each(|key| {
+      let key = Value::String(key.to_string());
+      if clash_config.contains_key(&key) {
+        let value = clash_config[&key].clone();
         new_config.insert(key, value);
       }
     });
@@ -297,12 +323,12 @@ pub async fn activate_profile(profile_item: &ProfileItem, info: &ClashInfo) -> R
     )?
   };
 
-  let server = format!("http://{}/configs", info.server.clone().unwrap());
+  let server = format!("http://{}/configs", clash_info.server.clone().unwrap());
 
   let mut headers = HeaderMap::new();
   headers.insert("Content-Type", "application/json".parse().unwrap());
 
-  if let Some(secret) = info.secret.clone() {
+  if let Some(secret) = clash_info.secret.clone() {
     headers.insert(
       "Authorization",
       format!("Bearer {}", secret).parse().unwrap(),
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 4953f1eb29e75d3e56e8b7e54d0d435862f1f745..e219f88c5cbb207e4bec2107829f6631efaf6901 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -41,14 +41,11 @@ fn main() -> std::io::Result<()> {
         }
         "restart_clash" => {
           let clash_state = app_handle.state::<states::ClashState>();
+          let profiles_state = app_handle.state::<states::ProfilesState>();
           let mut clash = clash_state.0.lock().unwrap();
-          match clash.restart_sidecar() {
+          let mut profiles = profiles_state.0.lock().unwrap();
+          match clash.restart_sidecar(&mut profiles) {
             Ok(_) => {
-              let profiles = app_handle.state::<states::ProfilesState>();
-              let profiles = profiles.0.lock().unwrap();
-              if let Err(err) = profiles.activate(clash.info.clone()) {
-                log::error!("{}", err);
-              }
               let window = app_handle.get_window("main").unwrap();
               window.emit("restart_clash", "yes").unwrap();
             }
diff --git a/src-tauri/src/utils/config.rs b/src-tauri/src/utils/config.rs
index 4d8e13e88cc990019bc77a776bdd0a394047f72d..04a33cc78010a707d3738e4a4f1f8673d56b400b 100644
--- a/src-tauri/src/utils/config.rs
+++ b/src-tauri/src/utils/config.rs
@@ -1,6 +1,4 @@
-use crate::utils::dirs;
 use serde::{de::DeserializeOwned, Serialize};
-use serde_yaml::Mapping;
 use std::{fs, path::PathBuf};
 
 /// read data from yaml as struct T
@@ -32,17 +30,3 @@ pub fn save_yaml<T: Serialize>(
     Err(_) => Err("can not convert the data to yaml".into()),
   }
 }
-
-/// Get Clash Core Config `config.yaml`
-pub fn read_clash() -> Mapping {
-  read_yaml::<Mapping>(dirs::app_home_dir().join("config.yaml"))
-}
-
-/// Save the clash core Config `config.yaml`
-pub fn save_clash(config: &Mapping) -> Result<(), String> {
-  save_yaml(
-    dirs::app_home_dir().join("config.yaml"),
-    config,
-    Some("# Default Config For Clash Core\n\n"),
-  )
-}
diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs
index 96cb9c45697a4ed656b2ab4dbade75e664b6f83b..21b18c1847eb367559259b5f7cf12e717af1d98d 100644
--- a/src-tauri/src/utils/resolve.rs
+++ b/src-tauri/src/utils/resolve.rs
@@ -39,7 +39,7 @@ pub fn resolve_setup(app: &App) {
   }
 
   *profiles = ProfilesConfig::read_file();
-  if let Err(err) = profiles.activate(clash.info.clone()) {
+  if let Err(err) = profiles.activate(&clash) {
     log::error!("{}", err);
   }