Build Mihomo Rule Providers: GitHub Hosting and Auto-Pull the latests
Why Put Mihomo Rules in a GitHub Rule Provider? from Practice
A long rules: list is easy to bring up 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 will want to stay direct.
Over time, the profile becomes a mixture of subscription data and personal policy. Every edit then has the same risks: a provider pull the latest can overwrite it, a typo can invalidate the full YAML file, and it is difficult to tell which change caused a routing result to shift.
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 straightforward place to review changes, keep a history, and share a settled raw-content address with more than one device.
Your key configuration retains the policy that decides how traffic is routed; the provider holds the list of domains, IP ranges, or all-in-one classical rules that you want to manage separately.
This separation is useful whether you maintain a small personal list or a larger team rule set. You get to pull the latest 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 get to inspect the provider file and the rule that references it instead of searching through a particularly 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.
Defining a provider does not hands-free 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.
Compatibility check: Rule-provider entrys 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 entrys.
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 a bit than a GitHub web page, and Mihomo must be able to parse the downloaded data.
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.
Prepare a Versioned Rule File on GitHub Lessons Learned
Create a repository for rule files, or choose a suitable existing repository. A public repository is the simplest entry for a normal Mihomo installation because the core can fetch its raw file over HTTPS without an interactive sign-in.
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.
Bring up with one file containing a short, focused list. For a domain-behavior provider using YAML, a practical file looks like this:
payload:
- DOMAIN-SUFFIX,example.org
- DOMAIN,login.example.net
- DOMAIN-KEYWORD,service-name
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.
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 easy to follow message such as “Add login host for work service.” Git history gives you a useful audit trail: you get to 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 settled branch.
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 in their own words. The raw address typically follows a pattern like this:
https://raw.githubusercontent.com/OWNER/REPOSITORY/BRANCH/rules/work.yaml
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 will want to contain the YAML file, not a GitHub sign-in screen, a 404 page, or an HTML document.
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 a bit than embedding a personal access token in a profile that may be shared.
A branch URL such as main is straightforward 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 pull the latest the configured URL when you approve a new version.
A pinned URL push ups 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.
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 in the Wild
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. Replace the URL, local path, provider name, and policy with values that exist in your own configuration.
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 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.
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.
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 problem message: 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.
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 built-in.
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 will want to be before or after a local-network exception; routing private addresses through a remote group is often not what users expect.
After saving, reload or activate the profile using your client’s normal configuration workflow. Watch the Mihomo log for YAML parse problem messages, a provider download failure, or a missing policy name. Then generate a connection to a domain that will want 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.
Refresh, Test, and Troubleshoot Stale or Failed Providers Hands-On Notes
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 push up a ruleset that changes only once a week.
Particularly 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 are expected to adopt it, a bit than copying an interval from an unrelated example.
During initial setup, test refresh deliberately instead of waiting for the scheduled interval. A good number of clients expose a rule-provider or profile pull the latest action; use the control that pull the latests the provider or reloads the profile, and check the Mihomo log for the result. A handful of Mihomo control panels 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 will want to be followed by an inspection of the loaded provider content and a connection test against one of its entries.
For a solid 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.
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, bring up by comparing the raw file in a browser with the content or pull the latest 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 pull the latest 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.
When downloads fail, test from the same machine and network where Mihomo be up and runnings. 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 hands-free uses that variable; confirm the client’s core routing path and inspect its connection or log view.
A parse failure by built-in 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 a bit than an HTML problem message page. Watch for invisible formatting problems introduced by a text editor, including tabs used for indentation.
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 a bit than a large collection of real services. Record which rule will want 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 full workflow.
Keep an eye on cache paths when running multiple clients or profiles. Two separate Mihomo instances will want 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 pull the latests as expected.
Use a settled path supported by your client, avoid editing the cached file as though it were the GitHub source of truth, and pull the latest 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.
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 pull the latest. If you want a client workflow that makes profile management and Mihomo rule testing easier to follow than editing files without context, Clash provides easy to follow setup guidance and access to compatible client entrys; you get to browse the downloads and choose the tool that fits your system.