What to sync: shared rules, device-specific settings

Sharing a Clash config between a PC and phone usually doesn't mean copying the same live YAML file to every device. Instead, have each device use the same proxies and routing rules while keeping system-specific settings separate. A subscription provides the proxy sources, the config organizes proxies and rules, and the client imports, updates, and starts the core. Each layer has its own state, so copying a file once won't synchronize everything.

For example, Windows may use 127.0.0.1:7890 as its system proxy, while phones typically route traffic through the system VPN interface. Both devices can use policy groups with the same names, but that doesn't mean they should share TUN settings, network interface names, or file paths. Android per-app proxy settings also aren't interchangeable with desktop process rules.

Config layer Good candidates for syncing Keep device-specific
Proxies and subscriptions Subscription URLs, proxy lists, update policies Device-specific credentials, traffic limits, or connection limits
Routing policies Domain rules, policy group names, rule-set references Local network exceptions, process rules, app exclusion lists
Runtime environment Common fields verified on each platform Listening ports, controller interface, TUN, DNS interception

Option 1: Use the same subscription URL on each device

If you only need the same proxy list on your PC and phone, importing the same subscription URL on both is the simplest approach. First check that your provider allows multiple devices, then review simultaneous connection limits, traffic accounting, and plan restrictions. Being able to copy a config doesn't mean your account allows unlimited concurrent connections.

Check what the subscription returns

  • Full Clash YAML: Usually includes proxies, proxy-groups, and rules. Import it as a remote config if your client supports that option.
  • Proxy list: When used as a proxy provider, it commonly has proxies as its top-level key. It won't provide the policy groups and routing rules needed for a complete config.
  • Base64-encoded proxy links or another core's format: Import support depends on whether the client can parse or convert the format. A .yaml extension alone doesn't guarantee compatibility.

In particular, distinguish remote config updates from proxy-providers updates. A remote config update may replace the entire config, while a provider update mainly refreshes its proxy list. Updating a proxy provider won't automatically replace the main config's rules with new rules from your provider. Check how the target core actually parses the URL before using a full config URL as a proxy provider.

Updates aren't instant synchronization

For supported HTTP proxy providers, interval: 3600 sets the update interval to 3,600 seconds, or one hour. The client's automatic remote config update schedule is a separate setting; this field doesn't control it. Phone sleep, background restrictions, or a stopped client can all delay updates.

  1. Import the subscription on the first device and check the proxy count, policy group names, and config load log.
  2. Import the same URL on the second device, trigger an update, and make sure it hasn't loaded an outdated local copy.
  3. Set a consistent target update interval, such as one hour. Confirm both clients support that interval and can update in the background.
  4. When your provider changes its proxies, check the update time on each device. Don't assume the phone has updated just because the PC has.

This option takes the least maintenance, but whether routing rules match depends on the subscription and local overrides. If the phone automatically adds rules during import and the PC doesn't, the two devices will still behave differently.

Option 2: Store configs and rules in a private repository

If you need to maintain your own domain exceptions, rule order, or configs for multiple devices, a private Git repository works well as a version-controlled source. It provides change history and rollback, but it's not a real-time client sync service and doesn't solve authentication for client downloads.

Separate shared and device-specific files

clash-config/
├── shared/
│   └── rules.yaml
├── desktop/
│   └── override.yaml
├── mobile/
│   └── override.yaml
└── README.md

This is an example of how to organize files, not a directory convention that Clash recognizes automatically. A client won't merge files just because a directory is named shared. The main config must reference rule sets through rule-providers and include them using RULE-SET rules. Override files also require a client that supports the relevant merge or import mechanism.

If you're using a YAML domain rule set, the following shows the expected format. example.com is a documentation example domain, not a recommendation for a business address to bypass the proxy.

payload:
  - "+.example.com"

This format can be used with rule providers configured with behavior: domain and format: yaml. The main config still needs to define the provider name, how to fetch it, and which policy to use for matching traffic. A rule-set file doesn't specify an exit node and can't replace the complete rules list.

Handle private repository credentials separately

  • Access in a browser doesn't guarantee client access: Your browser may already have an authenticated session, but core requests usually won't inherit those cookies.
  • Download links may expire: A raw file URL with temporary authorization parameters may return a login page or an error after it expires.
  • Authentication support varies by client: Test each client individually if the URL requires custom request headers or a dedicated authentication flow.
  • Keep subscription credentials out of commit history: Making a repository private limits who can access it, but doesn't eliminate the risk of exposure through history, cloned copies, or backups.

Git is best for storing rule source files without subscription tokens; inject private URLs through local config. If you need to publish a generated config, restrict access and make sure the publishing process doesn't log its full contents. Don't make a private config public just to make it easier for your phone to fetch.

Keep rollback separate from deployment

On your desktop maintenance machine, use the commands below to review changes and undo a bad commit. After creating a rollback commit, each client still needs to fetch and load the config again. A successful Git operation doesn't mean the phone's config has changed.

git diff -- shared/rules.yaml
git add shared/rules.yaml
git commit -m "Update shared domain rules"
git log --oneline -5
git revert HEAD

Option 3: Combine a subscription with local overrides or scripts

Let the subscription handle proxy changes and local overrides preserve your custom settings. This is a practical compromise for most multi-device setups. The key is to keep overrides in a separate layer provided by the client, rather than editing a subscription cache file that gets replaced on every update.

How rules are merged matters more than the file contents

Clients may use shallow or deep merges, replace lists, or provide a dedicated prepend mechanism. The same YAML snippet may append rules in one client but replace the entire list in another. The following shows fields intended for the final config; it isn't a universal import format for all clients:

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

mixed-port is a combined HTTP and SOCKS listening port. Using port 7890 on two different devices normally won't cause a conflict; a conflict can occur when two processes on the same device try to bind to the same address and port. Check the client's interface and runtime config to see whether its mobile app lets you override the port.

Review rule lists carefully. If you want a local domain rule to run before the fallback rule, you need to change the order, not simply append a line to the end of the file. Once MATCH handles all remaining traffic, rules appended after it won't run. Policy group names referenced by shared rules must also exist in the final config.

Scripts are a client feature, not a universal core setting

Some desktop clients provide a JavaScript hook for modifying the config object after a subscription loads. The entry point, execution timing, and available APIs are client-specific, so you can't copy the script directly to every Android or iOS client. Don't confuse this feature with scripting capabilities in legacy Clash configs.

  1. Start with static overrides for fixed settings to reduce reliance on a script runtime.
  2. Use client scripts only when you actually need to generate content dynamically from proxies or policy groups.
  3. Document the target client, supported versions, and test date for each script. Recheck its output after updating the client.
  4. Inspect the final runtime config, not just whether the script was saved successfully.

Platform differences: DNS, TUN, and core support

The Clash ecosystem includes different cores and GUI clients. Even two clients using mihomo may behave differently because of core versions, client-generated settings, or system permissions. Check the actual core and its version when assessing compatibility; don't assume every field is interchangeable just because an app has Clash in its name.

Area How to handle across devices Where to verify
TUN routing Set permissions, routes, and exclusions separately on each device Startup logs, system VPN status, connection list
DNS listener Don't copy desktop-only bind addresses and ports Final DNS config and port binding logs
Process and app rules Maintain desktop process names separately from mobile app selections Rules matched by actual app connections
File paths Use working directories supported by each client Provider download results and file read errors

DNS fake-ip mode uses synthetic addresses that the core processes to handle connections. Don't treat a device's runtime DNS cache as config that needs syncing. Upstream DNS reachability may also change when a phone switches from Wi-Fi to cellular. Test the same config on both network types.

iOS apps with similar proxy features may not use mihomo or accept full Clash YAML directly. Before choosing an app, check its subscription import formats, rule semantics, and local override support, then decide which source files to share. When converting configs for a different core, review protocol options and rule behavior; seeing the proxy names is not enough.

Verify updates: make sure both devices loaded the same version

Config sync needs a repeatable verification process. The steps below are a suggested checklist, not measured performance results for any particular client. Menu names vary, so look for the relevant controls for remote config updates, runtime config, connections, and logs.

  1. Record the source: Note the config name, subscription update time, and short Git commit ID for shared rules. Don't include the full subscription token.
  2. Refresh manually: Update the remote config on both devices. If you use providers, also check when the proxy and rule providers were last updated.
  3. Confirm a successful load: Check the logs for YAML parsing errors, unknown policy groups, provider fetch failures, or port binding failures.
  4. Check the final config: Confirm the mode is rule, your overrides are still present, and the fallback rule remains at the end.
  5. Test real connections: On each device, visit one address expected to bypass the proxy and one expected to use it. Check the matched rule and exit node in the connection list; a successful latency test only confirms that its test target is reachable.
  6. Test network changes: Verify the phone on both Wi-Fi and cellular. On desktop, check that local network services remain accessible as expected.

If the PC works but the phone doesn't, first confirm which config the phone actually loaded and when its providers last updated. Then check VPN permissions, background refresh, DNS, and protocol support. Don't switch every rule to global proxy mode as a first step: it may temporarily bypass the routing issue, but it also removes useful clues for troubleshooting.

Recommended setups and credential safety

  • Share proxies only: Use the same subscription URL on each device and keep device-specific settings local. Focus on account limits and update status.
  • Share proxies and a few exceptions: Combine a subscription with separate overrides. Prefer static rules supported by both clients, and verify how each handles list merging.
  • Maintain several devices over time: Store rule source files and change history in a private repository, keep subscription credentials on each device, and generate or import platform-specific configs as needed.
  • Generate policy groups dynamically: Run the process on a maintenance device that supports it, then deliver compatible results to other devices. Don't assume a phone can run a desktop script.

A subscription URL usually contains credentials. QR codes, exported config files, and log screenshots may expose the same access. Before sharing screenshots, redact query parameters, proxy passwords, and controller secrets. If someone else has obtained the URL, reset the subscription token in your provider account and update every device. Deleting a chat message or making a repository private again won't invalidate a URL that's already been copied.

The controller interface is also not a shared endpoint to expose to your phone. Don't expose external-controller to the public internet for remote management. Multi-device sync is about distributing configs and rules, not sharing access to a device's local controls. Keeping the shared layer focused and preserving device-specific settings is usually easier to maintain than trying to make every YAML byte identical.