mihomo vs. the Clash Core
See why Clash Meta was renamed mihomo, how their protocols, rule sets, and DNS features compare, and which fields to check when migrating a config.
First, distinguish the core, client, and legacy forks
Bottom line: If you need newer protocols, more granular rules, or an actively maintained core, consider mihomo first. If your existing config is stable, verify compatibility before routing live traffic through the new core.The main differences are feature coverage and maintenance—not a name change that makes every node faster. Connection quality still depends on the route, server settings, and local network.
Clash is a proxy core that handles traffic forwarding, rule matching, DNS, and more. Desktop and mobile clients provide subscription management, a system tray, system proxy settings, and permission controls. Clash Meta was a fork of Clash and was later renamed mihomo. Older documentation, config templates, and client settings may still use the Meta name; that usually reflects the project’s history, not a need to install a second core.
“Original Clash” needs some clarification: historically, there was an open-source core as well as the closed-source Clash Premium, and their features were not identical. The original project stopped being maintained in 2023. Don’t attribute every former Premium feature to the open-source version, or assume that updates to third-party clients mean the original core is maintained again.
Protocol support: new types don’t guarantee compatibility
mihomo adds support for more protocols and transports on top of the existing proxy features. The practical difference is that an older core may not parse VLESS, Hysteria2, or TUIC nodes in a subscription, while a compatible mihomo build can. Usability still depends on the specific version, fields, and server configuration—don’t rely on the node’s display name alone.
| Feature | Original open-source Clash | Why choose mihomo |
|---|---|---|
| Shadowsocks、VMess、Trojan | Supports the basic types; specific algorithms and transport options depend on the version. | Retains support and adds some algorithms, transports, and connection options. |
| VLESS and REALITY | No equivalent support to that in mihomo. | Supports VLESS and, in supported configs, REALITY; these are concepts at different layers. |
| Hysteria2、TUIC | Does not support these newer node types. | Provides implementations for these types. UDP-based connections also require support from both the local network and the server. |
| Rule sets and TUN | Premium’s feature list does not apply directly. | Supports rule providers and TUN, making it suitable for more complex traffic routing and traffic interception. |
When migrating nodes, check these three groups of settings
- Protocol credentials: The server address, port, password, or UUID must match the server settings.
443is a common TLS port number, but it doesn’t prove that a node uses HTTPS. - Transport settings: Match the WebSocket path, Host, gRPC service name, and other parameters individually. A YAML file loading successfully doesn’t mean the handshake settings are correct.
- TLS and REALITY: Check
servername, the fingerprint, and, where applicable,reality-opts. Don’t useskip-cert-verify: trueto mask an incorrect domain or certificate configuration.
If the subscription converter has already dropped nodes using newer protocols, upgrading the core won’t bring them back. Check the subscription format provided by the service, the converter output, and the config the client actually applies. Confirm the node types are preserved before investigating handshake failures; this makes troubleshooting much faster.
Rules and rule sets: preserve order and distinguish file formats
The basic matching logic hasn’t changed: in rule mode, rules are evaluated in order, and the first match determines which policy handles the connection. Basic rules such as DOMAIN, DOMAIN-SUFFIX, and IP-CIDR still matter. Unmatched traffic is usually caught by MATCH at the end. New features won’t fix an incorrect rule order.
mihomo offers more match conditions, such as filtering connections by process name, destination port, or logical combinations. However, process detection depends on the operating system, permissions, and how traffic is intercepted. Having PROCESS-NAME in a config doesn’t mean every platform can retrieve the expected process information.
RULE-SET is not a node subscription
proxy-providersprovides nodes; its contents must ultimately be parseable as proxy configs.rule-providersprovides match entries, which are then referenced byRULE-SETand assigned a policy.behavior: domain,ipcidr, andclassicaleach impose different requirements on entry contents; changing a file extension alone won’t make them interchangeable.- mihomo’s
mrsis a rule set format. The original Clash can’t use it directly, and it isn’t meant to be edited as ordinary YAML text.
A config migrated from Premium may already contain rule-providers and RULE-SET. If migrating from the original open-source core, don’t assume these fields were available before. The complete sample below is a minimal config skeleton for validation. It intentionally omits remote subscriptions, and its only policy-group option is direct connection.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxy-groups:
- name: Select exit
type: select
proxies:
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,Select exit
This config only verifies loading, ports, and rule structure; it doesn’t provide proxy routes. Once you add actual nodes, add a valid node or provider to the policy group. Don’t put MATCH before specific rules, or leave a rule pointing to a policy group that has been renamed or removed.
DNS differences: check resolution paths and startup dependencies
The original Clash already supports DNS and Fake-IP, so it’s inaccurate to say you need mihomo to use Fake-IP. mihomo differs in offering more control over resolution and ways to combine it with traffic routing. For example, nameserver-policy selects a resolver for specific domains, while proxy-server-nameserver handles proxy server domain lookups separately.
In fake-ip mode, domains resolve to mapped addresses, which the core then uses to handle connections. redir-host is closer to returning the actual resolved address. The right choice depends on app compatibility and how traffic is intercepted. If you run into issues with LAN device discovery, a specific game, or a corporate intranet, identify the relevant domains and traffic paths instead of adding every domain to a filter list.
Three DNS fields that are easy to confuse
| Field | What it does | What to check when migrating |
|---|---|---|
default-nameserver |
Used for bootstrap lookups, such as resolving the domain names of DNS servers. | Keep a working IP-based bootstrap address to avoid relying on a resolution path that isn’t available when the resolver starts. |
proxy-server-nameserver |
Specifies a resolver for proxy node server domains. | The node’s domain must resolve before it can connect. Avoid a loop where resolving the node requires routing through that same node. |
respect-rules |
Routes upstream DNS connections according to the configured rules. | If enabled, check node domain resolution and rule routing together; don’t just copy a Boolean value. |
TUN and clients: permissions matter, not just the toggle
A system proxy usually affects only apps that honor system proxy settings. TUN uses a virtual network interface to intercept IP traffic that matches the routing rules. mihomo supports TUN, but whether it works depends on system permissions, the virtual adapter, routing rules, and other VPN software. Enabling TUN won’t change the server protocol or give a route UDP forwarding if it doesn’t support it.
- Test the regular proxy first: Use the system proxy or an explicit HTTP proxy to confirm the node connects, then introduce TUN. This avoids troubleshooting two kinds of issues at once.
- Then check permissions: Desktop clients may use a service component to obtain the required permissions. When running the core directly, grant it the network management capabilities required by your operating system.
- Finally, check routing and DNS: Use
auto-route,auto-detect-interface, and DNS interception as appropriate for your network. Pay particular attention to multiple network adapters, corporate VPNs, and virtual machine networks.
Don’t mistake the mixed proxy listener on 7890 for a TUN interface port, or enter the controller port 9090 in your browser’s proxy settings. The controller is for managing the core from a client, not for proxying regular web traffic. If you configure it, restrict it to a loopback address where possible and set access credentials.
Migrate an old config: validate in six steps instead of overwriting it
Most basic YAML structures carry over, but “the old config starts” and “the new config works as intended” are two separate checks. Unknown fields may be ignored, while certain rules or nodes may fail during later loading stages. Keep the original config and client environment, and validate changes incrementally in a separate copy.
- Back up the config sources: Save the original subscription, client overrides, and currently active config separately. The subscription file shown in the client may not be the file ultimately passed to the core.
- Record the runtime environment: Note the operating system, client version,
mihomo -voutput, and whether system proxy or TUN is enabled. Shut down other instances before switching to avoid port conflicts. - Test the config: Run the command below from the config directory. If rule providers use relative paths, make sure the working directory matches the actual runtime environment.
mihomo -v
mihomo -t -f ./config.yaml
- Identify the error type: Fix YAML syntax or type errors first; if a policy group is missing, check its name; if a node type isn’t recognized, check the core version and subscription output. Don’t keep refreshing the subscription as soon as you see an error—that can overwrite useful evidence.
- Test an actual connection: After starting the core, use an explicit proxy request to check the listener, node, and TLS, then inspect the logs to see which rule matched. Passing a config test doesn’t replace verifying network access.
- Restore features one at a time: Add remote rule sets, DNS policies, process rules, and TUN last. Test after each change to identify which one introduces a problem.
curl -I --proxy http://127.0.0.1:7890 https://example.com/
This command assumes the mixed port is 7890 and proxy authentication is disabled; adjust the port if needed. An HTTP response proves only that this particular request completed—not that every rule, UDP app, or TUN setup works. Also test one destination expected to connect directly and another expected to use the proxy, then compare the policy names in the logs.
What if a subscription update reverts your config?
If you manually edit a file managed by a subscription, the next refresh will likely replace your changes with the server’s version. Use the current client’s supported override, merge, or scripting mechanism to preserve local changes, and check the merge order. Merge syntax varies by client; an override snippet for one client isn’t necessarily a native mihomo field.
Choosing a core: migrate only what your needs require
- Need newer protocols? Choose a client with a suitable mihomo version, and confirm the subscription output preserves all node fields.
- Need complex routing? Check support for rule providers, process detection, DNS policies, and your target platform. Don’t compare clients only by whether their UI has a “rule mode” button.
- Have a stable legacy setup? Validate a copy before replacing your everyday setup. The goal is to get the features and maintainability you need, not simply to change names.
When choosing a client, compare platform support and core options in the client comparison. To check protocol fields, consult the protocol guide. The definitive check is the version actually running, its load logs, and the connection results: migration is reproducible only when nodes parse, rules can be traced, and DNS paths are clear.