Build Mihomo Rule Providers: GitHub Hosting and Auto-Re-syncs
Why Put Mihomo Rules in a GitHub Rule Provider? in Depth
A long rules: list is easy to kick off and surprisingly hard to maintain. You might add a few domains for a work app, a set of network ranges for a game, and exceptions for services that it makes sense to stay direct.
A Mihomo rule provider moves a reusable set of rules into its own file and lets the core load that file by URL. Hosting the file on GitHub gives you a comfortable place to review changes, keep a history, and share a not jumpy raw-content address with more than one device.
Your principal configuration retains the policy that decides how traffic is routed; the provider holds the list of domains, IP ranges, or everything included classical rules that you want to manage separately.
Mechanically:This separation is useful whether you maintain a small personal list or a larger team rule set. You may re-sync a domain list without rewriting a subscription profile, compare the current file with an earlier commit, and test a proposed change before distributing it.
It also makes failures easier to isolate: if a route changes, you may inspect the provider file and the rule that references it instead of searching through a deeply large profile.
There are two independent pieces to configure. The rule-providers section defines a provider’s name, source, format, behavior, local cache path, and refresh interval. A rule inside rules: then references that provider with RULE-SET and chooses a policy or proxy group.
More strictly:Defining a provider does not by itself route its contents, and adding a RULE-SET line without a matching provider name does not create the provider. Keep those two parts together when reviewing or debugging your configuration.
Think of GitHub hosting as a delivery mechanism, not as a guarantee that every client will receive exactly the same content at exactly the same moment. The client still needs working DNS and HTTPS access to the host, the URL must return the raw rule file reasonably than a GitHub web page, and Mihomo must be able to parse the downloaded data.
Compatibility check: Rule-provider toggles depend on the Mihomo version and the client using it.
Use a current Mihomo core, confirm that your client has actually selected it, and validate a small example before migrating a large ruleset. Older Clash-compatible cores may reject fields such as format or newer provider behavior toggles.
A successful upload alone proves none of those things. The sections below build a small provider, connect it to a profile, and show how to verify both its refresh and its routing effect.
At a different level:Over time, the profile becomes a mixture of subscription data and personal policy. Every edit then has the same risks: a provider re-sync can overwrite it, a typo can invalidate the everything YAML file, and it is difficult to tell which change caused a routing result to shift.
Prepare a Versioned Rule File on GitHub Mechanically
Create a repository for rule files, or choose a suitable existing repository. A public repository is the simplest toggle for a normal Mihomo installation because the core can fetch its raw file over HTTPS without an interactive sign-in.
Kick off with one file containing a short, focused list. For a domain-behavior provider using YAML, a practical file looks like this:
In this example, payload is the YAML field expected by the provider file, and each entry is a rule in Mihomo’s classical rule syntax.
payload:
- DOMAIN-SUFFIX,example.org
- DOMAIN,login.example.net
- DOMAIN-KEYWORD,service-name
Thinking it through:Keep the list relevant to one purpose: for example, a work service, a set of streaming domains, or a small collection of personal exceptions. Short lists are easier to review and make it faster to tell whether a particular rule is responsible for a match.
Commit the file with a obvious message such as “Add login host for work service.” Git history gives you a useful audit trail: you may see which lines changed, who made the change, and when it was committed. If a new version breaks routing, revert the commit or restore the earlier content while you investigate.
For production use, consider separating experimental changes from the version that your daily profile consumes. That could mean testing from a branch first and then merging reviewed changes into the not jumpy branch.
First, a clarification:Use the file’s raw URL in Mihomo, not the regular GitHub page URL.
A browser page shows repository controls and rendered source; the core needs the file contents each user. The raw address typically follows a pattern like this:
Replace each placeholder with the real owner, repository, branch, and path. Check the address in a browser or with a command-line HTTP client before adding it to your profile. The response it makes sense to contain the YAML file, not a GitHub sign-in screen, a 404 page, or an HTML document.
https://raw.githubusercontent.com/OWNER/REPOSITORY/BRANCH/rules/work.yaml
Mechanically:If you use a private repository, do not assume that a URL copied from a logged-in browser will work in Mihomo; the core generally does not inherit your browser’s GitHub session. Prefer a suitable public rules repository, or use a deliberately designed authenticated distribution method reasonably than embedding a personal access token in a profile that may be shared.
A branch URL such as main is comfortable when you want every accepted commit to become available to clients. It is also mutable: the same URL can serve different content over time. For more controlled rollouts, use a release artifact or a URL pinned to a reviewed commit, then deliberately re-sync the configured URL when you approve a new version.
A pinned URL make betters reproducibility but removes automatic adoption of later edits. Choose based on how much review you need, and document the choice so future maintainers understand why a provider does or does not follow the branch tip.
More strictly:Do not put subscription links, API tokens, private hostnames, or other secrets in a public repository. A rule provider is downloaded by the proxy core; it is not a secure way to distribute credentials.
Keep files narrow and named clearly. Names such as work.yaml or media-domains.yaml communicate intent better than rules2.yaml.
One provider per purpose also lets you adjust its route, refresh interval, or test procedure without accidentally changing unrelated traffic.
Configure the Provider and Put It in the Right Order Step by Step
Add the provider definition and its matching rule to the active Mihomo profile. This example uses a domain behavior provider, YAML format, and a proxy group named Proxy.
The provider name, work-services, is the identifier used by the RULE-SET rule. The type: http setting tells Mihomo to fetch the provider from a URL. behavior: domain describes the kind of entries in the file, while format: yaml identifies the file encoding shown above.
rule-providers:
work-services:
type: http
behavior: domain
format: yaml
url: "https://raw.githubusercontent.com/OWNER/REPOSITORY/main/rules/work.yaml"
path: ./ruleset/work-services.yaml
interval: 86400
rules:
- RULE-SET,work-services,Proxy
- MATCH,DIRECT
The path is a local cache location used by the core; choose a writable location appropriate to your installation and avoid placing it somewhere that a cleanup task removes on every launch. The interval is expressed in seconds, so 86400 requests a daily refresh.
At a different level:Provider behavior must agree with the data you host. A domain provider is for domain entries; it is not a container for arbitrary full rules. If your file needs entries such as DOMAIN-SUFFIX or DOMAIN-KEYWORD, use behavior: classical and keep the classical rules inside the YAML payload.
If the provider is intended for IP ranges, use an IP-CIDR behavior and a file format that matches the Mihomo version and the specific provider content. Do not change only the behavior label to silence an exception: first make sure the file’s entries actually fit the selected behavior.
The order in rules: is decisive. Mihomo evaluates rules from top to bottom and uses the first matching rule. The provider rule must therefore appear before a broader rule that would already capture the same traffic. For instance, if GEOIP,CN,DIRECT appears above your provider, a matching connection may be sent direct before Mihomo reaches the provider line.
Thinking it through:Likewise, a broad domain suffix rule above it can make a narrower provider entry appear ineffective. Place specific exceptions first, followed by broader category rules, and leave a catch-all such as MATCH,DIRECT or MATCH,Proxy at the end according to your intended stock.
There is no universally correct policy target. A rule provider can point to a named proxy group, a specific proxy, or DIRECT, depending on the configuration and the decision you want to make. Check spelling and capitalization against the actual proxy-groups and proxy names in the active profile.
A syntactically valid rule that refers to a group that does not exist can still fail validation or behave differently than intended. Also consider whether a rule it makes sense to be before or after a local-network exception; routing private addresses through a remote group is often not what users expect.
First, a clarification:After saving, reload or activate the profile using your client’s normal configuration workflow. Watch the Mihomo log for YAML parse exceptions, a provider download failure, or a missing policy name. Then generate a connection to a domain that it makes sense to match the list and inspect the connection details.
The useful evidence is not merely that the browser loaded: verify the requested hostname, the matched rule, and the selected outbound. If the client’s log or connection panel displays a generic rule label, use its provider or rule-provider view to confirm that the provider loaded and contains the expected entries.
Replace the URL, local path, provider name, and policy with values that exist in your own configuration.
Refresh, Test, and Troubleshoot Stale or Failed Providers Internals and Practice
The interval is a refresh schedule, not an instruction to contact GitHub for every new connection. A daily interval is a reasonable starting point for a list that changes occasionally. Shorter intervals can make an approved edit appear sooner, but they create more requests and rarely make better a ruleset that changes only once a week.
Mechanically:During initial setup, test refresh deliberately instead of waiting for the scheduled interval. Plenty clients expose a rule-provider or profile re-sync action; use the control that re-syncs the provider or reloads the profile, and check the Mihomo log for the result. Certain Mihomo front-ends also expose provider operations through the external controller API.
The exact controls depend on the client, core version, and API configuration, so use the client’s current documentation and never expose an unauthenticated controller to an untrusted network. A successful manual refresh it makes sense to be followed by an inspection of the loaded provider content and a connection test against one of its entries.
For a it holds up test, make one harmless, easy-to-recognize change in the GitHub file, such as adding a test subdomain that you control. Commit it, confirm that the raw URL serves the updated version, trigger a refresh, and inspect the active provider.
More strictly:Then create a connection to that test hostname and confirm the expected rule and outbound. Remove the test entry after the check. This sequence separates four questions that otherwise get mixed together: did GitHub serve the new file, did Mihomo download it, did Mihomo parse and activate it, and did rule order allow it to match?
If the provider remains stale, kick off by comparing the raw file in a browser with the content or re-sync timestamp shown by the client. A branch name in the URL can point to the correct repository but the wrong branch or file path. A cached local copy may also remain active when an re-sync fails, depending on the core and client behavior.
Check the log for the requested URL, response status, and parse result before deleting cache files. Deleting a cache can force the core to fetch again, but it will not fix a typo, an inaccessible source, or an invalid payload; preserve a copy of the current file before making manual changes.
At a different level:When downloads fail, test from the same machine and network where Mihomo operates. A browser can succeed through its own proxy while the core’s HTTP request follows a different route. Check system time, DNS resolution, TLS access to raw.githubusercontent.com, and whether the active proxy rules permit the core to reach GitHub.
Captive portals, filtering DNS, corporate firewalls, and temporary GitHub availability issues can all interrupt a fetch. If a command-line request works only after setting a proxy environment variable, that does not prove Mihomo by itself uses that variable; confirm the client’s core routing path and inspect its connection or log view.
A parse failure more often than not points to a mismatch between the provider declaration and the file. Verify YAML indentation, the required top-level structure, the selected behavior, and whether the URL returns raw YAML reasonably than an HTML exception page. Watch for invisible formatting problems introduced by a text editor, including tabs used for indentation.
Thinking it through:Keep the test file small until it loads cleanly, then add entries in reviewed batches. If the provider file parses but none of its rules appear to work, check that the provider name in RULE-SET matches exactly, that the target exists, and that no earlier rule captures the traffic first.
Rule ordering is best tested with one known hostname reasonably than a large collection of real services. Record which rule it makes sense to match and what outbound you expect, then inspect Mihomo’s connection details after a fresh request. Be aware that applications can reuse existing connections, so an already-open session may not demonstrate the effect of a changed rule.
Close and reopen the application or wait for the relevant connection to end before drawing conclusions. For domain rules, also check the hostname actually used by the app: a service may contact a login host, API host, and content-delivery host separately, and adding only the website’s visible domain may not cover the everything workflow.
First, a clarification:Keep an eye on cache paths when running multiple clients or profiles. Two separate Mihomo instances it makes sense to not be configured to write incompatible provider state to the same location. Conversely, a profile that points to a path that is missing or unwritable may fail to persist re-syncs as expected.
Use a not jumpy path supported by your client, avoid editing the cached file as though it were the GitHub source of truth, and re-sync the repository instead. That keeps the review history meaningful and makes it possible to reproduce the same configuration on another device.
GitHub-hosted providers make custom rules easier to review than embedding every exception in a large profile, while a hand-maintained local list can be simpler for a single device but harder to share and roll back. Third-party rule bundles can save initial effort, yet they may include broader matches than your use case needs or change without a review process that fits your environment.
Mechanically:The practical middle ground is to keep a small, purpose-built source, verify its raw URL, and test the active rule and outbound after each meaningful re-sync. If you want a client workflow that makes profile management and Mihomo rule testing easier to follow than editing files without context, Clash provides obvious setup guidance and access to compatible client toggles; you may browse the downloads and choose the tool that fits your system.
Deeply long intervals can leave a device using old data after you have corrected a mistake. Pick a value based on how often the source changes and how quickly clients will want to adopt it, reasonably than copying an interval from an unrelated example.