First, work out which layer has stopped being maintained
Clash projects broadly split into three layers: the core, the GUI client, and configs and rule sets. The core handles protocol parsing, DNS and TUN routing; the client handles the UI, subscription management and the system proxy toggle; the config layer is profile files and rule-set files. The three layers talk to each other through YAML configs and local ports, so as long as the interfaces stay the same, any layer can be replaced on its own.
Work out which layer has stopped being maintained before deciding whether to touch your configs. Judge by the release date of the latest tag and the last commit on the default branch — star counts and download numbers tell you nothing.
| Layer | Typical signals | Real impact | What to do |
|---|---|---|---|
| Core | Repository archived, last release more than 12 months ago; the original Clash stopped at v1.18.0 (August 2023) | New protocols and DNS features are no longer merged; new rule-set formats can't be parsed | Swap the core; most of the profile can be reused |
| Client | No new release for 9+ months, issues left unanswered for a long time | UI and subscription management stuck on an old version; TUN may not work with newer OS releases | Swap the client; import subscriptions and profiles as they are |
| Rule sets | No commits to the rule repository for 6 months | Domain and IP lists gradually go stale, so routing accuracy drops | Change the rule source; update the url in rule-providers |
- In the client, open Settings → Version Info or About and note two version numbers: the UI version and the core version, in the form v1.18.0, v1.19.5.
- Open the releases page of the relevant repository and check the date of the latest tag to confirm whether development has really stopped.
- Open the profile directory and check whether the config comes from a subscription URL or a local file. The first can be rebuilt; the second has to be backed up first.
If only the client layer is discontinued, the change is minimal
Keep your existing profiles and rule sets and simply switch to a UI that is still maintained. The core, subscriptions and rule sets stay as they are, and migration usually takes under ten minutes.
Export your config assets before migrating
Config assets fall into three groups: subscription URLs, local profile files, and settings you edited by hand in the client (ports, TUN toggle, launch at startup, rule overrides). The first two export completely; the third only survives if you write it down item by item. Do the export with the proxy turned off, so a dropped connection can't break a subscription update.
Default profile directories by platform
| Platform | Client config directory | Default core directory |
|---|---|---|
| Windows | %APPDATA%\io.github.clash-verge-rev.clash-verge-rev\profiles\; older Verge builds use %APPDATA%\clash-verge\ | %USERPROFILE%\.config\clash\ |
| macOS | ~/Library/Application Support/io.github.clash-verge-rev.clash-verge-rev/profiles/ | ~/.config/mihomo/ |
| Linux | ~/.config/io.github.clash-verge-rev.clash-verge-rev/profiles/ | ~/.config/mihomo/ or /etc/mihomo/ |
| Android | Use the export item in the app's Profiles menu; the exported file usually lands in /sdcard/Download/ | App-private directory; not readable without root |
Export steps
- Turn off the system proxy and TUN: Settings → System Proxy off, Settings → TUN Mode off.
- On the Subscriptions page, right-click the target profile → Copy Subscription URL, then paste it into a local text file and save it.
- For local-file profiles, copy the entire profiles directory to a backup drive, including the providers subdirectory.
- Note the ports: mixed port 7890, controller port 127.0.0.1:9090, DNS listener 1053.
- Note the rule-set sources: the url, interval and path of every entry under rule-providers.
A minimal portable config
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
unified-delay: true
tcp-concurrent: true
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- https://223.5.5.5/dns-query
- https://1.1.1.1/dns-query
proxy-providers:
main:
type: http
url: "https://sub.example.com/link/8f3c1a2b?flag=meta"
interval: 3600
path: ./providers/main.yaml
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 300
unified-delay and tcp-concurrent are mihomo-only fields; the original Clash throws a parse error as soon as it reads them. Keep or remove them depending on the target core version — every other field works on both.
Swapping the core: from original Clash to mihomo
The original Clash core stopped at v1.18.0; the Clash.Meta branch was renamed mihomo in 2024 and has moved on to the v1.19 series, with the TUN stack, DNS and rule-set formats still being updated. Most config fields share the same names; the differences are concentrated in features added over the past two years.
| Config field | Original Clash v1.18.0 | mihomo v1.19.x | Migration action |
|---|---|---|---|
mixed-port | Supported | Supported | No change needed |
tun.stack | Supports system / gvisor | Add the mixed value | Can keep the current value |
sniffer | Not supported | Supported | Can be added to restore domains masked by fake-ip |
format: mrs in rule-providers | Not supported | Supported | Switch to mrs to cut memory use |
geodata-mode、geox-url | Not supported | Supported | Add it when geo files are needed |
lazy in proxy-groups | Not supported | Supported | Optional; reduces idle health checks |
sub-rule (new in 1.19) | Not supported | Supported | Older cores throw a parse error |
Backward compatibility mostly holds: mihomo reads original Clash profiles directly, but the reverse fails to parse because of the extra fields. So migration only goes one way, from the old core to mihomo.
Replacing the core from the command line on Linux
# Stop the old core service
sudo systemctl stop clash
# Download and install the mihomo core (amd64 example)
curl -LO https://github.com/MetaCubeX/mihomo/releases/download/v1.19.5/mihomo-linux-amd64-v1.19.5.gz
gunzip mihomo-linux-amd64-v1.19.5.gz
sudo install -m 0755 mihomo-linux-amd64-v1.19.5 /usr/local/bin/mihomo
# Confirm the swap took effect
mihomo -v
# Run in the foreground with the old config to check for field parse errors
mihomo -d /etc/mihomo -f /etc/mihomo/config.yaml
Keep the foreground output running while you test; once the log shows no field errors such as parse error, exit and let systemd manage it. Running as a non-root user needs extra network capabilities:
[Unit]
Description=mihomo
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
LimitNOFILE=1048576
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Don't overwrite binaries from different cores in the same path
An old core process may still be running in the background and holding port 9090, which shows up as the config not taking effect after the swap. Confirm the process has exited before overwriting the binary.
Choosing a replacement client by platform
Three hard requirements when picking a replacement client: a built-in channel for downloading and updating the core, support for importing a profile directory directly, and both system proxy and TUN modes. A UI that meets all three is the cheapest to migrate to, because your subscriptions and port habits carry over unchanged.
| Platform | Available clients | Core | How configs are imported |
|---|---|---|---|
| Windows | Clash Verge Rev、FlClash、Clash Nyanpasu | mihomo | Paste a subscription URL, or drag a yaml file into the window |
| macOS | Clash Verge Rev、FlClash、Mihomo Party | mihomo | Same as above; the first TUN launch needs approval in system settings |
| Android | FlClash、Clash Meta for Android | mihomo | Paste a subscription in the app, or import from a local file |
| iOS | Clients on the App Store that provide a Network Extension, such as Shadowrocket, Stash and Loon | Their own cores | Most accept subscription URLs only and don't parse full yaml |
| Linux | Clash Verge Rev(AppImage / deb / rpm)、mihomo + systemd | mihomo | Config files go straight into /etc/mihomo |
On iOS, mind the regional difference: these clients are not available in the App Store in mainland China, so you need an account from another region to download them. Most also don't parse full yaml and accept subscription URLs only, so move any hand-written local rules into the subscription beforehand — otherwise rules will be missing after migration.
Order of operations when moving configs from an old client
- Install the new client first and don't uninstall the old one yet, so you can compare settings at any time.
- Import the subscription URL and wait for the profile to finish generating and the node list to appear.
- Work through your backup notes item by item: mixed port, controller port, TUN stack type, launch at startup, system proxy mode.
- Once the new client connects, disable the old client and uninstall its background service. Windows service mode and the macOS privileged helper each need to be removed separately, or they leave ports listening.
Post-migration checklist
Run these ten checks in order; together they cover the vast majority of migration leftovers. The commands assume default ports — swap in your actual values if you changed them.
- Core version:
curl -s http://127.0.0.1:9090/version— the version field it returns should match the tag you installed. - Proxy path:
curl -I -x http://127.0.0.1:7890 https://www.gstatic.com/generate_204— aHTTP/2 204response means the path is working. - DNS resolution: on Windows use
nslookup www.google.com 127.0.0.1; on macOS and Linux usedig @127.0.0.1 -p 1053 www.google.com. An address in the 198.18.0.0/16 range means fake-ip is working. - Rule matching: open the Connections page in the UI, visit a site in mainland China to see whether it goes DIRECT, then visit an overseas site to see whether it enters a proxy group.
- TUN routing: on Windows run
route print -4to check the TUN adapter and the 198.18.0.0 range; on Linux runip route show table all | grep 198.18. - Port usage: on Windows use
netstat -ano | findstr :9090; on macOS and Linux uselsof -i :9090to confirm only one process is listening. - Subscription update: trigger an update manually; the log should show no 403, 404 or TLS handshake failures.
- Rule sets on disk: check that files in the rule-set directory are non-zero in size and were modified just now.
- Launch at startup: reboot once and confirm the client starts automatically with the same system proxy state as before.
- Fallback path: disconnect the proxy nodes and confirm that sites covered by DIRECT rules are still reachable, which shows routing isn't pushing everything into proxy groups.
Common migration problems and fixes
Subscription update returns 403 or 404
Usually a User-Agent mismatch. Some servers return different formats depending on the UA, and when the new core's default UA differs from the old client's, the panel simply refuses. First look for the UA dropdown in the client's subscription settings and switch to clash; if that fails, the link itself has probably expired — copy a fresh one from the panel.
Rule-set download fails
With geodata-mode: true you need geoip.dat, geosite.dat or the matching mmdb files; mihomo tries to download them into the working directory and fails when the network is restricted. Put the files there manually, or point geox-url at an address you can reach.
TUN mode won't start
- Windows: install service mode first — the initial install also unpacks wintun.dll. If an older service is already installed, uninstall it in settings and install again.
- macOS: the first launch needs you to approve the network extension or privileged helper in system settings. If you denied it once, reset the authorization in settings and start over.
- Linux: to run as a non-root user, grant the binary network capabilities with
sudo setcap cap_net_admin,cap_net_bind_service+ep /usr/local/bin/mihomo.
Exits immediately on launch, or the config doesn't take effect
First check whether port 9090 is held by an old process, then look at the config file's indentation and encoding: YAML indented with tabs fails to parse outright, and the file should be saved as UTF-8 without BOM. Set the log level to log-level: debug — the log reports the exact line number, which is far faster than comparing the config line by line.
Migration really comes down to moving three things into a new shell: subscription URLs, profile files, and your port and mode habits. Keep those three and you can change clients as often as you like without disrupting daily use; rely only on where the toggles sit in the UI, and the next discontinued client will send you back to square one.