Kumo logoKumo

Overrides

Tweak a subscription without forking it. Merge operators, examples, and caveats.

An override is a small YAML or JavaScript file Kumo merges on top of a profile before Mihomo loads it. Overrides are the right tool for:

  • Adding personal rules ("send mygithub.com to a specific node").
  • Tweaking DNS settings without forking the upstream profile.
  • Replacing a noisy proxy group with one of your own.

Overrides live in ~/Library/Application Support/Kumo/overrides/files/ and an index file (overrides.json) maps which overrides are enabled in what order.

Merge order

Each time Kumo starts the core (or the active profile, override list, or order changes):

  1. Start with the active profile's YAML.
  2. Apply enabled overrides in their saved order.
  3. Apply Kumo-controlled keys (mixed-port, external-controller, find-process-mode, DNS block when TUN is on).
  4. Write the merged YAML to work/config.yaml.

If two overrides touch the same key, the later one wins.

Merge operators

Kumo understands two operator families. Both can be mixed in a single override file.

Sparkle-style prefix / suffix / replace

+rules:        # prepend
  - DOMAIN-SUFFIX,mygithub.com,DIRECT

rules+:        # append
  - DOMAIN-KEYWORD,ads,REJECT

key!:          # replace (overwrite the whole key)
mode!: rule

Clash Verge Rev-style prepend / append / delete

prepend-rules:
  - DOMAIN-SUFFIX,mygithub.com,DIRECT

append-rules:
  - DOMAIN-KEYWORD,ads,REJECT

delete-rules:
  - "MATCH,Proxy"           # delete the literal MATCH rule

Both styles compose. Kumo applies prefixes, suffixes, replacements, prepends, appends, and deletes in a defined order so the result is the same regardless of which spelling is used.

Worked example

Given a profile that includes:

rules:
  - DOMAIN-KEYWORD,google,Proxy
  - MATCH,DIRECT

And an override:

+rules:
  - DOMAIN-SUFFIX,myhomeserver.lan,DIRECT
rules+:
  - DOMAIN-KEYWORD,porn,REJECT
delete-rules:
  - "MATCH,DIRECT"
+rules:
  - MATCH,Proxy

The effective rule list becomes:

rules:
  - DOMAIN-SUFFIX,myhomeserver.lan,DIRECT
  - DOMAIN-KEYWORD,google,Proxy
  - DOMAIN-KEYWORD,porn,REJECT
  - MATCH,Proxy

JavaScript overrides

Drop a .js file. Kumo runs it in a sandboxed JS engine and expects an exported main(config) function that returns a mutated config. Use this when YAML cannot express the change.

// overrides/files/normalize-groups.js
export function main(config) {
  for (const group of config['proxy-groups'] ?? []) {
    if (group.type === 'select') {
      group.proxies = group.proxies.filter(p => !p.includes('Trial'));
    }
  }
  return config;
}

JS overrides see only the merged config so far. They cannot read or write files outside the sandbox.

Manage overrides

From the GUI: Overrides in the sidebar. Drag to reorder, click the checkbox to enable/disable, click an override to edit its content.

From the filesystem:

overrides/
  overrides.json        # ordered list, enabled flags
  files/
    rules.yaml
    normalize-groups.js
    ...

overrides.json and the files in files/ can be edited by hand. Kumo re-reads them on the next core reload.

Common pitfalls

  • mode!: rule does not change the current mode. It sets the profile's mode key on disk. If the mode was already switched at runtime, runtime wins.
  • Empty delete-rules in YAML evaluates to null, not an empty list. Use delete-rules: [] to explicitly disable it.
  • Override order matters. Disabling an override and re-enabling it drops it at the end of the list. Drag it back where it belongs.

The find-process-mode: always key is Kumo-controlled. If an override sets it to anything else, the Connections destination will stop showing app icons.

On this page