What to sync: share rules, keep device settings local
Think of “sharing one config” as sharing a config source—not loading the exact same final YAML on all three devices. Keep node sources, policy group names, and routing rules as consistent as possible, but manage local listening ports, TUN behavior, controller settings, and client preferences separately. That way, updating nodes won’t overwrite another device’s network settings.
First, distinguish the core from the GUI client. mihomo parses supported config, matches rules, and establishes proxy connections; the client handles subscription updates, config selection, overrides, and system integration. Clients differ in how these features are presented and stored. An iPhone client may not use mihomo at all. Being able to import a node subscription doesn’t mean it can fully apply the rules, DNS settings, and policy groups in a Clash YAML file.
- Good candidates for sharing: node sources, stable policy group names, domain rules, and rule sets supported by all your clients.
- Keep these local:
mixed-port,external-controller, controller secrets, and TUN or network interface settings. - Check compatibility: protocol support,
proxy-providers,rule-providers, DNS fields, and client-specific extensions.
Comparing the three sync methods
Subscription links are best for ongoing upstream node updates; iCloud folders work well for passing manually maintained files between a few devices; private Git repos suit users who want to review rule changes and roll them back. All three get config onto a device, but none syncs the active connection, selected node, or system proxy toggle.
| Method | Best for | How updates work | Main limitation |
|---|---|---|---|
| Subscription link | Nodes and full upstream config | Refresh the subscription on each device | Response formats and supported fields may vary |
| iCloud folder | Manually maintained YAML | Reimport or reload after the file syncs | The client may not keep reading the source file |
| Private Git repo | Rules, templates, and local override examples | Pull, review, and apply | Requires separate credential and deployment management |
If your main goal is to use the same nodes on Mac and your phone, start with a subscription. If you want a rule change to reach every device, establish a shared source of truth for rules first, then choose file sync or Git for distribution. Don’t copy each device’s entire client data folder just to share nodes.
Subscription links: import on each device, update from one source
Import and refresh workflow
- Confirm the subscription’s output format with the provider: a full Clash config, a node list, or a format for another specific client.
- Import the link from your Mac client’s config manager, refresh it once, verify the policy groups and rules are present, then enable the config.
- Import the same source on Windows and check whether the response matches. Some services return different formats based on request parameters or client identifiers.
- Choose a supported subscription type in your iPhone client and inspect the import. If it imports nodes only, configure rules and DNS separately.
Each client refreshes its subscription independently. Updating on Mac won’t refresh the iPhone for you, and background activity on mobile may be limited. As a starting point, set automatic updates to every 24 hours, then refresh manually when nodes change. Available intervals and background behavior depend on the client.
Prevent subscription updates from overwriting your changes
Edits to a downloaded subscription file may disappear on the next refresh. If your client supports overrides, keep local ports, DNS changes, and custom rules in a separate override. If it doesn’t, maintain a separate local config and decide how you’ll update its nodes. Where supported, node providers can also separate node updates from the main config.
Subscription URLs often contain access tokens, so treat them like passwords. Don’t include full links in public screenshots, logs, or repositories, and don’t send them to an unfamiliar online service just to convert formats. If a link is exposed, rotate its token with the provider and update the source on each device.
iCloud folders: sync files, then reimport
On your Mac, create a dedicated folder such as ClashConfig in Finder → iCloud Drive, and put only the configs you intend to share there. On iPhone, find it in Files → Browse → iCloud Drive. On Windows, install and sign in to iCloud, turn on iCloud Drive, then open the corresponding folder.
- Choose one device as the primary editor. Save
shared.yamlthere and wait for the upload to finish. - On the receiving device, make sure the file has downloaded locally and isn’t just a cloud placeholder.
- Use the client’s file import option to select the config, check that it parses correctly, then make it the active config.
- After making changes, validate them on one device first. Then reimport the file on the others or use the client’s reload feature if available.
The key difference is whether a client “reads the source file” or “imports a copy.” Some clients copy YAML into their own data folder. In that case, the iCloud file may change while the client keeps using an older copy. Temporarily change an easy-to-spot policy group name, reimport the file, and check whether the UI reflects the change to confirm which file is loaded.
Don’t edit the same YAML on two devices at once. File sync can create conflict copies, and manual merges can break indentation or rule order. Have one device edit at a time, keep the last working file, and confirm the update is active on the receiving device before starting the next round of changes.
Private Git: review rules and roll back config
Git works best for rules and config structure you maintain yourself—not account credentials. You can organize files in layers as shown below. These filenames are conventions, not names Clash or mihomo recognizes automatically. Import them explicitly in the client or combine them with your own build process.
clash-config/
├── shared.yaml
├── rules/
│ └── direct.yaml
├── local/
│ ├── mac.yaml
│ └── windows.yaml
└── .gitignore
Use shared.yaml for shared policy groups and rules, and local/ for device-specific settings. Exclude files containing real subscription URLs or secrets from commits. Adding a file to your ignore rules won’t remove secrets already in Git history, so you’ll still need to rotate those credentials. A private repo is only one layer of access control, not a reason to store every secret there long-term.
Commit, pull, and validate
git diff -- shared.yaml rules/
git add shared.yaml rules/
git commit -m "Reorder direct connection rules"
# Update the working copy on another desktop
git pull --ff-only
git pull --ff-only stops if branches have diverged, giving you a chance to resolve local changes instead of creating an unexpected merge commit. After a successful pull, reload the config in your client. If you don’t have a practical Git workflow on iPhone, use a trusted file import method to receive a release file; there’s no need to reproduce your entire desktop development setup on your phone.
In a mihomo-based desktop setup, test the final generated file before applying it. Here, effective.yaml is the file with shared content and local settings already combined. The command requires a mihomo executable available on your system.
mihomo -t -f effective.yaml
A successful config test means the core accepts the config; it doesn’t prove that remote nodes are reachable or that the system proxy is on. If something goes wrong, retrieve the previous file from Git and import or reload it. Rolling back the file won’t restore system network settings, so check those separately.
Local overrides: ports, TUN, and rule order
Mac and Windows can share routing logic while keeping their own entry-point settings. The following snippet shows local fields for a mihomo-based desktop setup, not a complete proxy config. It uses port 7890 for mixed traffic and binds the controller to the loopback address 127.0.0.1:9090.
mixed-port: 7890
allow-lan: false
mode: rule
external-controller: 127.0.0.1:9090
tun:
enable: false
Apply these fields through the client’s supported local settings or override mechanism; don’t assume every client merges YAML the same way. This is especially important for list fields: some mechanisms replace the entire list, while others prepend or append entries. After applying changes, inspect the final config to make sure existing proxy groups and rules haven’t disappeared unexpectedly.
- Ports: First check whether another process is using
7890. If you change the port, update terminal proxy environment variables and any proxy settings entered manually in apps. - TUN: Desktop setups involve permissions, routing, and coordination with other VPNs. iPhone usually uses a system network extension for traffic capture, so don’t copy desktop settings such as
tun.stackor interface names directly. - DNS: Keep DNS settings that work on each device. If you need a shared DNS policy, check support field by field; a YAML parser accepting the config doesn’t guarantee consistent behavior.
- Controller: There’s usually no need to expose it across devices. If you need LAN access, configure authentication and access controls separately; don’t simply bind it to every network interface.
Put custom rules before the fallback rule
Clash-style rules are matched in order. This snippet shows why domain-based direct rules must come before the final fallback. PROXY must be the name of a proxy or policy group already defined in the full config.
rules:
- DOMAIN-SUFFIX,example.org,DIRECT
- MATCH,PROXY
If you append a new rule after an existing MATCH, it usually won’t be reached. Shared rules should also avoid relying on policy group names that exist on only one device. Keep group names consistent across devices, then let each device select different nodes within a group. Matching group names doesn’t require identical node selections.
Exceptions for corporate domains, LAN addresses, or specific Wi-Fi networks are better kept in the local layer. They may only work on the network your Mac is connected to. Copying them to a phone on cellular may be pointless or send traffic somewhere unexpected.
Verify sync and troubleshoot common issues
For each update, check in this order: source → final config → rule match → actual traffic route. That’s more useful than repeatedly reinstalling the client. Validate on one device first, then roll out the change to the others to narrow down any problems.
- Check the source: Compare subscription update times, file modification times, or Git commit records to confirm all three devices received the same change.
- Check the config: Verify the active config name, the number of policy groups, and whether the new rule appears in the effective config.
- Check traffic capture: On desktop, check the system proxy or TUN status. On iPhone, check the client connection status and look for conflicts with other VPNs.
- Check routing: Visit one service expected to connect directly and another expected to use a proxy. In the connection log, verify the matched rule, policy group, and actual node.
Same subscription, different node lists
Check the output format, protocol support, and local filters first, then compare refresh times. The subscription service may also generate different content based on the client identifier. Don’t assume sync failed based only on list length, and never share a full response containing access tokens just to compare results.
Same rules, different traffic routes
That may be expected. The currently selected node in a manual group is usually stored locally on each device. Automatic test groups measure from each device’s network. A Mac on home Wi-Fi and an iPhone on cellular may select different nodes even with identical policy group definitions. To reproduce an issue, temporarily select the same node on each device and compare the results.
File is updated, but the client still uses old content
First check whether the client imported a copy, whether a different config is active, and whether the client reloaded successfully after the subscription update. Keep the current working config, then test by importing again. For ongoing use, a good setup is one shared subscription or rule source plus local overrides on each device. Add Git if you need rule history; use iCloud for occasional manual file transfers. The clearer the sync boundaries, the easier cross-platform issues are to diagnose.
For port and rule fields, see the YAML Config Guide. For first-time import and traffic capture, see the Setup Guide.