mihomo core · rule-based routing reference
Clash Verge Official Site Client downloads & setup
This site covers mihomo core notes, subscription import steps, and rule-based routing syntax, with download links for five-platform clients and core binaries collected on the download page; first-time users can finish in four steps: install, import a subscription, pick a mode, and verify connectivity.
Config drawer
Five config keys that decide how traffic is routed
mode, dns, tun, proxy-providers, and external-controller are the five sections most often edited in a config file. Switch on the left to see what each one solves; the matching config.yaml snippet sits on the right.
mode decides what the core does with a connection once it arrives. rule walks the rule list from top to bottom and applies the policy of the first match; global sends all traffic through a single outbound, and direct is effectively a temporary off switch for the proxy. Keep rule for everyday use, and switch to global only when you need to tell whether a broken request comes from a bad rule or an unreachable node. The mode toggle in the client UI edits this exact line, so after switching back to rule, make sure the policy group holds at least one working node — otherwise connections that match PROXY fail outright.
mode: rule # rule / global / direct log-level: info ipv6: false
The dns section decides who resolves domain names and which path those lookups take. With enhanced-mode set to fake-ip, the core hands the app a virtual address first and does the real resolution inside the proxy tunnel, so plaintext queries never appear on the local network; with redir-host it resolves before connecting, which is more compatible but easier for middleboxes to observe. Put encrypted resolvers (DoH or DoT) in nameserver, and use fallback to catch poisoned answers. After editing this section, restart the core — reloading the config alone sometimes leaves the resolver cache in place.
dns: enable: true enhanced-mode: fake-ip nameserver: - https://223.5.5.5/dns-query fallback: - tls://1.1.1.1:853
tun makes the core create a virtual network adapter and take over traffic at the system level, so it no longer matters whether an app honors the system proxy settings. Terminal commands, containers, and game clients — programs that never read proxy config — only follow your rules once tun is on. Check permissions first: Windows needs the client running as administrator, and macOS asks you to approve a network component the first time. For stack, gvisor has the best compatibility; system borrows the OS network stack for higher throughput but can clash with firewalls on some systems. Leave it off when you don't need system-wide capture.
tun: enable: true stack: gvisor # gvisor / system / mixed auto-route: true dns-hijack: - any:53
proxy-providers pulls subscription links out of proxies and lets the core fetch them on a fixed interval, so several policy groups can share one node set and a changed subscription URL only has to be edited in one place. health-check sets the URL and interval for availability probes; nodes that fail a probe are skipped in the policy group for the time being. path points at the cache file — if a fetch fails, the core keeps using the previous cache instead of wiping your nodes over one network hiccup. interval is measured in seconds; set it too low and the subscription service will rate-limit you, so start at 3600.
proxy-providers: sub-a: type: http url: "https://example.com/api/v1/client/subscribe?token=xxxx" interval: 3600 path: ./providers/sub-a.yaml health-check: enable: true url: https://www.gstatic.com/generate_204 interval: 300
external-controller is the control API the core exposes; client UIs, third-party dashboards, and scripts use it to read the active policy, switch nodes, and list connections. GUI clients write this line automatically and generate a random key when they start the core — you only set it yourself when deploying the core by hand. It listens on 127.0.0.1:9090 by default, reachable from the local machine only. To expose it on a LAN or a server you must also set secret, otherwise anyone on the same subnet can rewrite your routing rules and node selection.
external-controller: 127.0.0.1:9090 secret: "your-password"
Platform downloads
Choose a client for your system
All five platforms still have clients under active development. The download page lists every available build per platform with system requirements and install notes, and core binaries have a section of their own.
Open-source ecosystem
Core, clients, and rule sets: who maintains what
The same config file can be driven by different clients, because the core is what actually parses it. Once you know what each of the three layers handles, switching clients or swapping the core doesn't mean rewriting your rules.
Clients and the core are two separate layers
mihomo parses the config, opens connections, and enforces rules; clients such as Clash Verge Rev and FlClash handle the UI, subscription management, and starting or stopping the core process. One core can be driven by different clients, and since the config format is the same, switching clients is just a matter of exporting the profile and importing it again — rules and policy groups don't need rewriting.
Fork lineage and config compatibility
The original Clash core is no longer maintained; the community kept building on its config format, producing the Meta and mihomo line, which adds protocol support for VLESS, Hysteria2, and TUIC along with config features such as rule-providers and proxy-providers. Nearly every client still being updated now runs mihomo as its core, so mihomo's documentation is the reference for which fields a config file accepts.
Rule sets are maintained on a separate track
Routing rules are split into list files by type — domain, IP, process, and so on — maintained by separate projects and fetched on demand through rule-providers. Updating rules then needs no change to your config file; the client only has to keep the reference. When choosing a rule set, update frequency and how finely it categorizes matter more than the raw entry count.
Updates come in three layers
Client updates come in three layers: the UI, the core, and subscriptions plus rule sets. Most clients treat the core as a replaceable component — you can pin a version in settings or swap the binary by hand — while subscriptions and rule sets are fetched on the interval each one configures. When connections misbehave, first check that the three layers agree on config and timing, then read the actual error.
FAQ highlights
Four questions that come up most before you start
These are the four most-asked questions; the full categorized Q&A lives on the FAQ page, and term definitions are in the glossary.
What to check first when a subscription update fails
First confirm the subscription URL opens in a browser and returns content, then go back to the client and check the update log and timestamp. Most failures come from an expired link, a domain blocked by local DNS, or temporary rate limiting on the subscription service; re-importing the link usually clears out stale cache and old config.
The client shows connected, but pages won't open
Check three things in order: whether the dns section is enabled and points at encrypted resolvers, whether the mode got switched to direct, and which rule the target domain matched in the connection log. If all three look right, try another node to see whether the outbound itself is the problem.
What's the difference between rule mode and global mode
rule matches the rule list entry by entry, sending different domains through different outbounds; global sends everything through one outbound. The mode only changes how the core handles traffic, not the nodes themselves, so switching to global is the fastest way to isolate a problem.
Which section of the config file holds custom rules
They go in the rules section, written as three parts: type, match value, policy name. Once the list grows, split it into separate rule set files and pull them in with rule-providers, so rule updates don't touch the main config.
Tech notes
Recent troubleshooting and selection write-ups
Long-form articles grouped by problem type: platform onboarding, client comparisons, migrating off discontinued clients, and certificate troubleshooting — each with steps you can follow.
Getting started on iOS: App Store client install and full config import steps
Walks through the iOS flow — searching the App Store, regional differences, importing a subscription link, and the on-demand settings — and shows how to confirm rule-based routing is actually working after the first connection.
Read the full article →After a client stops updating: exporting config, swapping the core, and alternatives
A discontinued client doesn't invalidate your config. Export the profile and rules first, then pick a client still under development for your platform or move to the mihomo core directly — with a checklist for before and after the migration.
Read the full article →Mainstream Clash clients compared: picking one by platform and habits
Compares mainstream clients across four dimensions — core version, platform coverage, configuration style, and release cadence — with recommendations for Windows, macOS, mobile, and desktop, so you don't find out after installing that it doesn't fit.
Read the full article →