Clash Verge Configuration Guide

Start with a minimal Mihomo YAML configuration, then add DNS, TUN, proxy groups, routing rules and rule providers. For changes that should survive profile updates, use Clash Verge Extension Config or Extension Script instead of editing the source subscription directly.

  • CoreMihomo (formerly Clash Meta)
  • FormatYAML · UTF-8
  • IndentationTwo spaces, never tabs

Clash Verge Base Configuration

This minimal Mihomo configuration shows the fields that define a basic Clash profile: the mixed proxy port, routing mode, logging, external controller, proxy groups and a final catch-all rule. Proxy nodes can come from a remote subscription or a local configuration.

Mihomo YAML · config.yaml
# Basic ports
mixed-port: 7897          # Shared HTTP and SOCKS port
allow-lan: false          # Set to true to let LAN devices connect
bind-address: "*"
mode: rule                # rule / global / direct
log-level: info           # silent / error / warning / info / debug
ipv6: false

# External control (Clash Verge manages this; only matters if you call the API yourself)
external-controller: 127.0.0.1:9097
secret: ""

# Proxies: supplied by your subscription; leave empty or add your own nodes
proxies: []

proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - AUTO
      - DIRECT
  - name: AUTO
    type: url-test
    url: http://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true     # Pull in every node from the subscription

rules:
  - GEOIP,LAN,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

Note include-all can populate a proxy group from available providers or profiles without listing every node manually. MATCH is the final fallback rule, so more specific routing rules should appear before it.

Mihomo Ports and External Controller

Proxy ports define how local applications connect to Mihomo. The external controller exposes the Mihomo API used by Clash Verge and other local tools to inspect or modify runtime state.

Mihomo ports
# Option 1: a single mixed port, recommended
mixed-port: 7897

# Option 2: separate listeners, useful for tools that only speak one protocol
# port: 7890             # HTTP
# socks-port: 7891       # SOCKS5
# redir-port: 7892       # Linux / macOS transparent proxy
# tproxy-port: 7893      # Linux TProxy

allow-lan: false         # Only enable to share with phones, TVs and so on
bind-address: "*"        # Limit sources when allow-lan is true, e.g. "192.168.1.0/24"

external-controller: 127.0.0.1:9097
secret: "replace-with-your-own-random-string"

Caution allow-lan permits other devices to reach the local proxy listener. Only enable it when LAN access is intentional, restrict the listening scope where possible, and protect the external controller with a non-empty secret if it is exposed beyond localhost.

Mihomo DNS Configuration

DNS behavior affects domain matching, Fake-IP routing and whether applications resolve names through the path you expect. In Clash Verge, DNS settings ultimately belong to the Mihomo configuration, so test them together with the active routing mode and TUN settings.

Mihomo DNS
dns:
  enable: true
  ipv6: false
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip          # fake-ip or redir-host
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:                 # Domains that skip fake-ip
    - "*.lan"
    - "*.local"
    - "localhost.ptlogin2.qq.com"
    - "+.stun.*.*"
  default-nameserver:             # Only resolves the DoH domains below
    - 223.5.5.5
    - 119.29.29.29
  nameserver:                     # Regular queries
    - https://223.5.5.5/dns-query
    - https://doh.pub/dns-query
  proxy-server-nameserver:        # Resolves node domains, avoiding a loop
    - https://223.5.5.5/dns-query
  nameserver-policy:              # Pick an upstream per domain
    "geosite:cn": https://223.5.5.5/dns-query
    "geosite:geolocation-!cn": https://dns.cloudflare.com/dns-query

Note proxy-server-nameserver is used to resolve proxy-server hostnames separately from normal requests, which helps avoid circular dependencies. nameserver-policy lets specific domain groups use different upstream resolvers when the profile requires that behavior.

Clash Verge TUN Configuration

TUN creates a virtual network interface so Mihomo can route traffic from applications that do not follow operating-system proxy settings. It also changes routing behavior, so permissions and platform-specific network conditions matter.

Mihomo TUN
tun:
  enable: true
  stack: mixed                    # gvisor / system / mixed
  device: Mihomo
  auto-route: true                # Take over system routing
  auto-detect-interface: true     # Detect the outbound interface
  strict-route: false             # Stricter route isolation, enable if needed
  mtu: 1500
  dns-hijack:
    - any:53

# With TUN, pairing DNS with fake-ip is recommended
dns:
  enable: true
  enhanced-mode: fake-ip

Caution If traffic becomes unreachable after enabling TUN, first test TUN and system proxy independently so you can isolate routing conflicts. TUN startup problems are often related to permissions, service state, virtual adapters or other networking software; see the proxy and TUN troubleshooting section.

Clash Proxy Groups and Node Selection

Proxy groups define how Clash/Mihomo chooses an outbound route. Common group types include manual selection, latency-based selection, failover and load balancing, with filters used to include or exclude nodes by name.

proxy-groups
proxy-groups:
  # Manual select: the main entry point, pointing at the groups below
  - name: PROXY
    type: select
    proxies: [AUTO, HK, JP, US, DIRECT]

  # Auto latency test: lowest latency wins
  - name: AUTO
    type: url-test
    url: http://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true

  # Failover: used in order, moves on only when one fails
  - name: FALLBACK
    type: fallback
    url: http://cp.cloudflare.com/generate_204
    interval: 300
    include-all: true

  # Load balance: spread connections across one group
  - name: BALANCE
    type: load-balance
    strategy: consistent-hashing   # or round-robin
    url: http://cp.cloudflare.com/generate_204
    interval: 300
    include-all: true

  # By region: filter names out of the full node list
  - name: HK
    type: url-test
    include-all: true
    filter: "(?i)香港|hong ?kong|hk"
    url: http://cp.cloudflare.com/generate_204
    interval: 300
  - name: JP
    type: url-test
    include-all: true
    filter: "(?i)日本|japan|jp"
    url: http://cp.cloudflare.com/generate_204
    interval: 300
  - name: US
    type: url-test
    include-all: true
    filter: "(?i)美国|united ?states|us"
    exclude-filter: "(?i)过期|剩余|官网"
    url: http://cp.cloudflare.com/generate_204
    interval: 300

Note filter and exclude-filter use regular expressions to decide which proxy names enter a group. The example includes Chinese region and subscription-status keywords because many real-world profiles use them in node names; adjust the pattern to match the naming convention in your own profile rather than copying it blindly.

Clash Routing Rules and Rule Providers

Mihomo evaluates routing rules from top to bottom and stops at the first match. Individual rules handle specific domains, processes, ports or networks, while rule providers load larger reusable rule collections.

routing rules
rules:
  # LAN and loopback, no domain resolution needed
  - GEOIP,LAN,DIRECT,no-resolve
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve

  # By process: send only specific programs through the proxy
  - PROCESS-NAME,Telegram.exe,PROXY
  - PROCESS-NAME,Telegram,PROXY

  # By domain
  - DOMAIN-SUFFIX,github.com,PROXY
  - DOMAIN-KEYWORD,google,PROXY
  - DOMAIN,ghcr.io,PROXY
  - DOMAIN-SUFFIX,cn,DIRECT

  # By port and protocol
  - DST-PORT,22,DIRECT
  - NETWORK,udp,PROXY

  # Rule sets: bulk domain / IP lists
  - RULE-SET,private,DIRECT
  - RULE-SET,reject,REJECT
  - RULE-SET,cncidr,DIRECT,no-resolve

  # Geo-based catch-all
  - GEOIP,CN,DIRECT
  - MATCH,PROXY
rule-providers
rule-providers:
  private:
    type: http
    behavior: domain
    format: text
    interval: 86400
    path: ./ruleset/private.txt
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/private.txt"
  reject:
    type: http
    behavior: domain
    format: text
    interval: 86400
    path: ./ruleset/reject.txt
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/reject.txt"
  cncidr:
    type: http
    behavior: ipcidr
    format: text
    interval: 86400
    path: ./ruleset/cncidr.txt
    url: "https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/cncidr.txt"

Caution The example rule-provider URLs are maintained by a separate community project, not by Clash Verge Rev. Make sure behavior matches the provider format: domain for domain rules, ipcidr for IP ranges and classical for full rule syntax.

Clash Verge Extension Config (formerly Merge)

Current Clash Verge versions call this feature Extension Config. It uses YAML to merge or override configuration fields after a profile is loaded, so reusable settings can remain separate from the source subscription. Older documentation may refer to the same feature as Merge Config.

Extension Config · YAML
# Extension Config merges or overrides YAML fields in the generated profile.
# Use it for settings that should stay separate from the source subscription.

unified-delay: false
log-level: warning

dns:
  enable: true
  ipv6: false
  enhanced-mode: fake-ip

tun:
  auto-detect-interface: true

Note Since Clash Verge v1.7.x, the old prepend-* and append-* rule workflow is handled through the profile's visual rule editor. Extension Config is now focused on YAML field merging and overrides. Use the visual rule editor when you need rules inserted before or after the profile's existing rule list.

Clash Verge Extension Script (formerly Script)

Extension Script uses JavaScript when YAML merging is not flexible enough. Clash Verge passes the generated configuration object into main, where the script can inspect or modify it before returning the final config.

Extension Script · JavaScript
function main(config, profileName) {
  // 1. Guard: these fields may be missing, so fill them in
  config.rules = config.rules || [];
  config["proxy-groups"] = config["proxy-groups"] || [];

  // 2. Drop placeholder nodes (traffic and expiry notices)
  const junk = /(剩余|到期|过期|官网|流量|订阅)/;
  config.proxies = (config.proxies || []).filter((p) => !junk.test(p.name));

  // 3. Build regional proxy groups from keywords
  const areas = [
    { name: "HK", re: /香港|hk/i },
    { name: "JP", re: /日本|jp/i },
    { name: "US", re: /美国|us/i },
  ];

  for (const area of areas) {
    const members = config.proxies
      .filter((p) => area.re.test(p.name))
      .map((p) => p.name);
    if (members.length === 0) continue;

    config["proxy-groups"].push({
      name: area.name,
      type: "url-test",
      url: "http://cp.cloudflare.com/generate_204",
      interval: 300,
      proxies: members,
    });
  }

  // 4. Put your own rules at the very front
  config.rules.unshift("DOMAIN-SUFFIX,my-internal.example,DIRECT");

  // 5. You must return the config object
  return config;
}

Note The config argument is the parsed configuration object, and current Clash Verge versions can also pass profileName. Use bracket notation for keys such as proxy-groups, and always return the modified configuration from main.

Clash Verge Configuration Troubleshooting

When Mihomo rejects a profile or a routing change appears to do nothing, check YAML syntax first, then ports, rule order, DNS, provider formats and whether the change was made in the correct Clash Verge extension layer.

Symptom Likely cause How to confirm
The config errors out on import Tabs used for YAML indentation, or a missing space after a colon Use two spaces everywhere; comment out sections in halves to narrow it down
Startup fails with a port-in-use error mixed-port conflicts with another proxy tool Pick a different port, or quit the program holding it
A rule has no effect An earlier rule matched first, or it sits after MATCH Check rule order; use the profile's visual rule editor for prepend/append rules and Global mode only as a temporary diagnostic
A rule set fails to load behavior doesn't match the list type, or the URL is unreachable Use domain for domain lists and ipcidr for IP ranges; open the URL to confirm it responds
It connects but pages won't load DNS misconfiguration, or fake-ip and redir-host mixed together Get one DNS setup working first; check whether fake-ip-filter is missing internal domains
Every node times out Node hostnames are resolved through the proxy, creating a loop Make sure proxy-server-nameserver points at a direct DNS server
Latency testing selects odd nodes Traffic and expiry notices in the subscription are treated as nodes Filter those names out with exclude-filter or a script
Changes disappear after a subscription update The subscription config itself was edited directly Move reusable changes into Extension Config, Extension Script or the profile's visual rule editor

Use Your Clash Verge Configuration

After the profile loads successfully, choose a proxy group or node and test the routing path with system proxy or TUN. For version-specific fields and behavior, check the current Mihomo and Clash Verge documentation.