RIME has had sync_dir for a long time (since librime-1.5 era, ~2017). The mechanism is well-documented in rime/home/wiki/UserGuide and github.com/Mintimate/oh-my-rime‘s English guide. But the docs assume you’ve been a RIME user for a while — they skip some “first-time installer” gotchas. This article covers the three-device workflow on Linux / Mac / Windows in 2026, with verification on Debian 13 + macOS Sonoma + Windows 11.

How RIME sync actually works

The unit of sync is the *.userdb.txt snapshot. When RIME accepts a phrase you typed (or when you redeploy), it writes a snapshot of the user dictionary into a per-device folder under your sync_dir. The installation_id controls which folder is yours.

The folder layout under your sync_dir (e.g. ~/Dropbox/RimeSync/) looks like:

Bash
RimeSync/
├── id-laptop-fred-m2/
│   ├── installation.yaml    # a copy of this device's installation_id + sync_dir
│   ├── default.custom.yaml  # the user-edited configs in your RIME root
│   ├── squirrel.custom.yaml # Mac-only
│   ├── luna_pinyin.userdb.txt
│   ├── wubi_pinyin.userdb.txt
│   └── ... (one userdb per active schema)
├── id-fred-officepc/
│   ├── installation.yaml
│   ├── default.custom.yaml
│   ├── weasel.custom.yaml   # Windows-only
│   └── ...
└── id-fred-x1carbon/
    └── ...

Two things to notice:

  1. Static dictionaries (.dict.yaml files, dicts/ folder, Lua scripts, the big .gram model) are not synced. They live at each device’s ~/.local/share/fcitx5/rime/, separately. The sync folders only contain user-modified .yaml and the userdb snapshots. If you want the same ice/frost/wanxiang schema on every device, you re-run Plum on each.
  2. The synchronizer does a snapshot-merge, not file sync. When you click “Sync”, RIME walks every id-* subfolder, reads each <schema>.userdb.txt, and merges entries into the local user dictionary. Conflicts are resolved by max-weight — the higher weight wins. So if you typed a phrase twice on laptop and three times on desktop, your desktop’s weight (3) becomes the canonical weight.

Step 1 — set the same sync_dir on every device

Pick a cloud folder that’s mounted on every device. Dropbox is the most-tested option because RIME’s first-class sync docs all use Dropbox as the example. iCloud Drive works, OneDrive works, Nutstore / 坚果云 works, a Syncthing peer works. Pick whichever you already have set up.

Decide on a folder name. Most people use RimeSync at the root of the synced folder:

  • Linux: ~/Dropbox/RimeSync/ (or wherever your Dropbox is mounted)
  • macOS: ~/Dropbox/RimeSync/
  • Windows: %USERPROFILE%DropboxRimeSync

The RIME installation.yaml file at each device’s ~/.local/share/fcitx5/rime/ controls this. Edit it to add sync_dir:

Yaml
# Linux: ~/.local/share/fcitx5/rime/installation.yaml
distribution_name: fcitx5-rime
distribution_version: 5.1.13
install_time: "Tue Jul 14 14:00:00 2026"
installation_id: "thinkpad-x1-linux"      # ← set per-device (see step 2)
sync_dir: "/home/fred/Dropbox/RimeSync"   # ← absolute path on this device
rime_version: 1.16.1

Yaml
# macOS Squirrel: ~/Library/Rime/installation.yaml
distribution_name: Squirrel
distribution_version: 0.16.2
install_time: "Tue Jul 14 14:00:01 2026"
installation_id: "macbook-pro-m2"          # ← different from the linux one
sync_dir: "/Users/fred/Dropbox/RimeSync"
rime_version: 1.8.5

Yaml
# Windows Weasel: %APPDATA%Rimeinstallation.yaml
distribution_name: Weasel
distribution_version: 0.16.2
install_time: "Tue Jul 14 14:00:02 2026"
installation_id: "office-pc-windows"       # ← different again
sync_dir: "C:\Users\fred\Dropbox\RimeSync"
rime_version: 1.8.5

Three rules:

  • Each device’s installation_id must be unique across all devices. RIME uses it as the subfolder name; collision means entries from two devices silently overwrite each other. Convention: lowercase letters + digits + - + _, no spaces, no Chinese. Pick a name you’ll recognize in ls ~/Dropbox/RimeSync/ six months from now.
  • sync_dir paths differ per OS. The Linux path uses /home/..., macOS uses /Users/..., Windows uses C:Users.... Avoid ~/ — it expands differently depending on how RIME was launched (it can be C:UsersfredAppDataRoaming~ on Windows, which is not what you want).
  • Windows paths in YAML need quoting. The backslashes are escape characters in YAML double quotes. Either use single quotes 'C:UsersfredDropboxRimeSync' (no escape processing) or use forward slashes 'C:/Users/fred/Dropbox/RimeSync' and let Windows normalize them.

Redeploy after editing installation.yaml. The RIME engine only reads it on deploy.

Step 2 — set installation_id deliberately

The first time RIME deploys with an empty installation_id field, it generates a random UUID (c5f45f7e-3c1c-4257-8ff7-bce78e9b5fb5-style). That’s fine — UUIDs are unique — but harder to read in ls. Most setups replace it with a meaningful string:

Yaml
installation_id: "fred-thinkpad-x1"   # better than a UUID

RIME checks installation_id characters when reading the file: only lowercase letters, digits, -, and _ will work cleanly. The upstream user guide says:

因爲 Rime 要以這個 ID 爲名創建文件夾,因此 ID 不得包含(所有涉及同步的文件系統)文件名中非法的字符;建議不要用中文,只用小寫字母、數字、橫線和下劃線。

A typo here is recoverable (edit, redeploy, sync) but causes a window where sync_dir/id-old-typo/ and sync_dir/id-fred-thinkpad-x1/ both exist. Just clean up the orphan with rm -rf.

Step 3 — first sync run

This is where most first-timers get confused. The flow:

  1. Redeploy on device A to write installation.yaml with the new sync_dir and installation_id.
  2. Open RIME’s tray menu and click “同步” / “Sync” on device A. RIME creates ~/Dropbox/RimeSync/id-fred-thinkpad-x1/ and dumps the local userdb snapshots in.
  3. Wait until Dropbox syncs the files (you can verify with ls ~/Dropbox/RimeSync/id-fred-thinkpad-x1/ on device B).
  4. Redeploy on device B, then click “Sync”. RIME sees its own empty user dictionary + the snapshot from A, merges them, writes a new snapshot.
  5. Done. From here, sync is one click per device per change.

If your distro’s RIME port doesn’t expose a “Sync” button in the tray menu (some don’t — e.g. older fcitx5-rime, some custom Linux builds), the same thing happens in two places: the desktop IME’s config UI exposes a sync button; or you can run librime-ctl (not always shipped) to invoke it from the CLI. On macOS, Squirrel exposes the “同步” button in its main menu. On Linux fcitx5-rime, the menu item is Rime → 同步... after you’ve added any IME entry to the active list.

If you’d rather make this automatic, the “Sync” button maps to rime_deployer --sync. Combine it with a cron / systemd timer on Linux:

Bash
# cron.d entry for one user: every 30 min sync
*/30 * * * *  fred  /usr/bin/rime_deployer --sync

Note the first run after enabling cron needs at least two sync’ing devices that have seen each other once via the GUI, or you’ll get an empty cache.

What gets synced, what doesn’t

The sync walk is:

  1. For each sibling id-* subfolder under sync_dir, RIME loads every <schema>.userdb.txt it finds.
  2. RIME’s user-dict merge code combines those snapshots into one in-memory user dictionary.
  3. RIME writes a fresh snapshot to this device’s own id-* folder.
  4. RIME also copies (one-way, always from local to remote) the following files from your local RIME root to the sync folder:
    • installation.yaml (always)
    • default.custom.yaml (if present)
    • <schema>.custom.yaml (if present)
    • Other hand-edited *.yaml files at the RIME root

NOT synced (per upstream doc):

  • The static *.dict.yaml dictionaries
  • The Lua scripts under lua/
  • The wanxiang-lts-zh-hans.gram (or any other .gram model)
  • The dicts/ folder under community schemas (rime-ice / rime-frost / rime-wanxiang’s per-vocab splits)
  • The build cache (build/*.bin files)
  • Configuration files inside subdirectories (like a schema’s own custom/)

The reason is not laziness — it’s that these files are static from one perspective and re-creating them is part of the install process. Reproducing the install (Plum + a couple of optional downloads) is the recommended way to get a new device in sync at the schema level.

If you DO want to carry schema files across (people managing a small fleet of identical devices often do), the cleanest path is git rather than the RIME sync mechanism:

Bash
# Linux & Mac: install once, then push to a private git repo
cd ~/.local/share/fcitx5/rime/   # or ~/Library/Rime on Mac
git init
git add . && git commit -m "starting config"
# Push to a private GitHub repo; pull on every other device

installation_id is part of installation.yaml — make sure to edit it on each clone, then commit. The sync mechanism still uses installation.yaml from each local file, not from git.

Migrating an existing user dictionary to a new schema

The wiki example is migrating luna_pinyin.userdb.txt (built up on stock luna_pinyin) to rime_mint.userdb.txt (the new schema you’re switching to). The recipe (verified against the wiki):

  1. Copy luna_pinyin.userdb.txt to your new schema’s filename. So rename the file from the old to the new schema ID. (rime_mint.userdb.txt for oh-my-rime, for example.)
  2. Edit the db_name line at the top of the file. Look near the top of the .userdb.txt; you’ll see a comment like #@/db_name = luna_pinyin. Change the right-hand side to the new schema ID.
  3. Put the renamed file in your sync_dir (any sibling id-* folder, or directly in sync_dir/).
  4. Click Sync. RIME merges it as if it came from another device.

The wiki warns about character-set issues:

If you used a Traditional Chinese dictionary before, you need to do a conversion from Simplified Chinese to Traditional Chinese in advance. Be careful not to convert all Tab to spaces.

That’s a real risk: a Notepad on Windows or a careless paste-through-IDE pipeline can rewrite tabs into 4 spaces, which silently breaks the userdb format (RIME expects tab-separated). Always re-tab after any conversion.

Common pitfalls

“I clicked Sync but nothing happened.”

Three things to check:

  1. installation.yaml exists and the YAML parses. Validate with python3 -c "import yaml; print(yaml.safe_load(open('installation.yaml')))".
  2. sync_dir path actually exists and is writable by the RIME process. Some Dropbox-installed-on-Linux configurations mount the folder under ~/.dropbox-dist/, not ~/Dropbox/. ls -la $sync_dir to confirm.
  3. Wait. The first sync can take 30-60 seconds even on a small user dictionary because of the merge pass. Open a second terminal and tail -F the RIME log (echo "log: $(cat ~/.cache/fcitx5/rime.log | tail -5)") — if you see “sync completed”, it worked.

“My phrases got merged but I lost earlier custom phrases.”

This happens when the sync_dir folder ended up with *two `id-subfolders pointing to the same physical machine**. The duplicate got selected over the original; the original's.userdb.txtwas discarded. Clean up: remove the orphanid-*/` folder, click Sync again.

“Both my laptops show the same installation_id.”

Means you edited installation.yaml and copied the file to both before deploying. Don’t sync before you’ve made the IDs unique. The fix: edit each installation.yaml in place, redeploy, then sync.

“Some schemas’ userdb syncs, others don’t.”

Schema name must match the userdb filename. RIME only syncs the userdb whose schema is currently active. If rime_ice.userdb.txt shows up on device A but not B, it means B doesn’t have rime_ice in its schema_list. Add it under default.custom.yaml schema_list, redeploy, sync.

“Sync wiped all my custom phrases after a clean install.”

Means the freshly-deployed device’s *.userdb.txt was empty (clear install), and the sync merged “nothing” with the older snapshot. RIME uses max-weight per phrase, so an empty entry doesn’t delete a non-empty one. But if you Deploy on a freshly-installed device before Sync, the deploy creates a fresh <schema>.userdb.txt from zero. Then Sync merges from the (older, populated) cloud folder. So the order is: Sync first, then Deploy. If you deploy’d first, just re-sync — the cloud is still there.

Mac-only thing: iCloud Drive vs Dropbox

~/Library/Mobile Documents/com~apple~CloudDocs/Rime/ works the same as a Dropbox folder, but expect one quirk: Apple randomly renames folders across upgrades (the AVFS / MobileSync background process). Set sync_dir to the absolute path inside Library/Mobile Documents/..., never a symlink. If iCloud renames the path, RIME fails to find the folder silently. Re-edit installation.yaml to the new path.

A common workaround: store the actual sync folder at ~/RimeSync-iCloud/, then symlink it into iCloud Drive’s documents directory and reference the absolute path (~/RimeSync-iCloud/) in installation.yaml. That way iCloud’s renaming is invisible to RIME.

Windows-only thing: file locks

Weasel (the official 小狼毫 Windows port) historically has had issues where the userdb file is locked while RIME is running. If you Deploy / Sync on device B while device A is using RIME, you’ll see a copy-conflict file (luna_pinyin.userdb.txt (Fred-PC's conflicted copy ...)) instead of a clean merge. The fix is to stop the IME on the other device during the first sync — or accept the conflict file as ground truth for that one device.

For more than two Windows machines, the cleanest pattern is to put Weasel on hold (Rime 暂停) during any sync window.

What next

If this got you set up across three devices, the natural next article is a deep-dive into .gram model selection and training — which wanxiang-lts-zh-hans.gram is for what use case, whether the smaller essay.txt is enough for shorter sentences, how librime 1.16 vs 1.17 differ on model loading. Tell me in the comments.


Sources verified July 2026: github.com/rime/home/wiki/UserGuide (the canonical sync doc), github.com/Mintimate/oh-my-rime English sync guide (the best third-party writeup), deepwiki.com/ssnhd/rime/2.4-synchronization-system (synced-config behavior on iCloud). wanxiang-lts-zh-hans.gram model file referenced as per upstream RIME-LMDG.

Last modified: 2026年7月14日

Author

Comments

Write a Reply or Comment

Your email address will not be published.