devAlice
← Multi-OS

File Sync — P2P Mac ↔ Windows Folders with Syncthing

Real-time folder sync between two machines without the cloud. Keep dotfiles / notes / projects identical anywhere.

Anyone using both Mac and Windows eventually asks: "That file I made today — how do I get it on the other machine?" USB, Dropbox, iCloud, OneDrive, Git, SCP — each has clear flaws. Cloud has size limits and privacy concerns; Git is wrong for binaries/intermediates; SCP lacks automation.

Syncthing solves it: P2P + open source + free. Two machines sync directly without a central server. Falls back to LAN when the internet is unreachable. This guide covers Mac + Windows 11 setup and practical sync patterns.

TL;DR

  1. Install Syncthing on both — brew on Mac, winget on Windows
  2. Exchange each machine's Device ID — one-time registration
  3. Share a folder — one side advertises, the other accepts
  4. .stignore to exclude deps / secrets — never sync node_modules or .env

Prerequisites

  • Mac: macOS 12+ (Homebrew installed) — Mac initial setup
  • Windows: Windows 10/11 (winget available) — Windows initial setup
  • Fastest when both are on the same LAN (also works across networks via internet)
  • Both machines must be online for sync (one waking from sleep triggers sync on wake)

1. Why Syncthing — Alternatives Compared

ToolModelSize limitData locationCostVerdict
Syncthing (pick)P2P, OSSDisk onlyYour machinesFreeM0–M2 recommended
iCloud DriveCloud5GB free / paid 200GB+Apple$/moMac-first, Win client limited
OneDriveCloud5GB free / paid 100GB+MS$/moWin-friendly, Mac works
DropboxCloud2GB free / paid 2TBDropbox$/moTiny free tier
Resilio SyncP2P, closedUnlimitedYour machines$/mo (Pro)Paid superset
GitVersion controlRepo limitsGitHub etc.FreeBad fit for big binaries/intermediates
rsync (manual)SyncUnlimitedYour machinesFreeNo automation

Syncthing strengths: no size limits, data only on your disk (privacy), free, equal clients on both OSes.

Weaknesses: both machines must be on simultaneously (not suitable for backup), conflicts resolved manually, GUI is rough (browser-based).

2. Install

Mac

brew install --cask syncthing
# Or as a background service (auto-start on login)
brew services start syncthing

GUI: http://127.0.0.1:8384 — admin UI in the browser.

Windows 11

# winget (no admin needed)
winget install -e --id Syncthing.Syncthing

Or Syncthing Windows Setup installer (with tray icon + auto-start).

After install, right-click the tray icon → "Open" to launch the GUI (http://127.0.0.1:8384).

Mac auto-opens the GUI; Windows opens via tray. Both use the same web UI.

3. First Pairing — Connect Two Machines

3.1 Get Device IDs

On each machine's Syncthing UI:

  1. Top-right ActionsShow ID
  2. Copy the long string (XXXXXXX-XXXXXXX-...)

3.2 Add Windows in Mac

  1. Mac Syncthing UI → Add Remote Device (bottom-right)
  2. Device ID: paste Windows's ID
  3. Device Name: Win11-Desktop (your choice)
  4. Save

3.3 Accept on Windows

Almost immediately Windows shows a notification: Device <Mac ID> wants to connectAdd Device → name MacBook-Pro → Save.

Both UIs now show each other as Connected (green).

Same LAN connects in 5s. Across the internet 1–2 min (after Discovery + Relay).

4. First Shared Folder

4.1 Mac → Windows Direction

Mac UI:

  1. Add Folder
  2. Folder Label: notes (your choice)
  3. Folder ID: notes-mac-win (unique, must match on both)
  4. Folder Path: /Users/{me}/Documents/notes
  5. Sharing tab → check Win11-Desktop
  6. Save

4.2 Accept on Windows + Pick Path

Windows UI notification: "MacBook-Pro wants to share folder 'notes-mac-win'"Add

  1. Folder Path: C:\Users\{me}\Documents\notes (mirroring Mac's structure helps)
  2. Save

4.3 Result

Wait until both folders show Up to Date (green). The first run copies everything one way, so duration scales with size. After that, changes propagate quickly (usually within 5s).

5. .stignore — What NOT to Sync

The common mistake is syncing node_modules / .git / .env. Dependencies should be rebuilt per machine; Git folders can corrupt mid-sync; .env is secret. Ignore them all.

5.1 Template Download

For dev folders:

.stignore
# Mac/Linux
curl -fsSL https://devalice.jaceclub.com/assets/multi-os/file-sync/stignore-dev.txt -o /path/to/folder/.stignore
shasum -a 256 /path/to/folder/.stignore
# Expected: f003177e7026492848825e42c4b4845d1c68f787b923ce44854cb47e9c859827
# Windows PowerShell
Invoke-WebRequest -Uri https://devalice.jaceclub.com/assets/multi-os/file-sync/stignore-dev.txt -OutFile C:\path\to\folder\.stignore
Get-FileHash C:\path\to\folder\.stignore -Algorithm SHA256

5.2 Apply

  1. Put .stignore at the sync folder root
  2. Syncthing UI → that Folder → EditIgnore Patterns tab → enable Use .stignore
  3. Trigger Rescan → ignored files are immediately excluded

5.3 Critical Ignores

PatternWhy
node_modules, .venv, targetDependencies — built per machine
.gitCorruption risk + use Git for that
dist, build, .nextBuild outputs — reproducible
.env, .env.local, *.pem, id_*Secrets — never sync
.DS_Store, Thumbs.dbOS metadata
*.log, tmpLogs / temporary

6. Practical Patterns

6.1 Dotfiles Sync

Don't sync the entire home dir (secret risk). Collect into a ~/dotfiles/ folder and symlink.

~/dotfiles/
├── .gitconfig
├── .zshrc
├── .vimrc
└── .tmux.conf
# Mac/Linux
ln -s ~/dotfiles/.zshrc ~/.zshrc
ln -s ~/dotfiles/.gitconfig ~/.gitconfig
# Windows — PowerShell profile lives elsewhere
ln -s C:\Users\me\dotfiles\Microsoft.PowerShell_profile.ps1 $PROFILE

Share ~/dotfiles/ via Syncthing. OS-specific branching via subfolders (dotfiles/common, dotfiles/mac, dotfiles/windows).

6.2 Notes Sync

Share your Obsidian / Logseq vault folder. Fewer conflicts than iCloud / OneDrive (Syncthing conflicts per-file, not per-line — still be careful with concurrent edits).

6.3 Project Source Sync (with caveat)

Rule: prefer Git when possible. Use Syncthing only for incidental files needing local-only sync (scratch, per-env config, experiment notes).

If you must sync the source folder, always include .git in .stignore. Mid-sync of Git internals risks reflog/index corruption.

6.4 Send Only / Receive Only

Folder types (Folder → Edit → Folder Type):

  • Send & Receive (default) — bidirectional
  • Send Only — this machine is master. Other side's changes ignored + rejected
  • Receive Only — receive-only. Local changes don't propagate

Backup-receiving machines set to Receive Only prevents accidental bidirectional overwrites. But real backups still want dedicated tools (restic, Time Machine).

7. Conflict Handling

When both sides edit the same file simultaneously, Syncthing auto-creates a conflict file:

  • foo.md (last-used version)
  • foo.sync-conflict-20260512-153012-DEVICE.md (the other version)

Procedure

  1. Open both and diff (VS Code "Compare with Active" or diff foo.md foo.sync-conflict-*.md)
  2. Unify into foo.md
  3. Delete the sync-conflict file

Frequent conflicts mean simultaneous editing in the same folder. For notes, split per-machine subfolders (notes/mac/, notes/win/) to avoid them.

8. Security

Device Authentication

  • Device ID is a public-key hash (TLS). No impersonation
  • New device requests require explicit approval on both ends

Data Transit

  • All traffic TLS 1.2+
  • Direct on LAN; via public Relay over the internet — Relay only forwards ciphertext

Recommended Settings

UI → Settings → GUI Authentication:

  • Set GUI Username + GUI Password (especially for laptops on external networks)
  • Without it, anyone on the same LAN can access http://your-ip:8384

UI → Settings → Connections:

  • Listen Address: default
  • NAT Traversal ✅ (auto hole-punching)

.stignore for Secrets

  • Always ignore .env, *.pem, id_*, .aws/credentials
  • This guide's stignore-dev.txt already does

Verification

Pass these on both machines:

  1. Create notes/test.md on Mac → appears on Windows within 10s
  2. Edit notes/test.md on Windows → reflects on Mac within 10s
  3. Delete notes/test.md on Mac → disappears on Windows within 10s
  4. Edit on both simultaneously → sync-conflict-... file appears (handle per §7)
  5. node_modules / .env etc. created on one side don't reach the other

Troubleshooting

Two Machines Can't See Each Other

  • Same LAN? (over internet, wait up to 5 minutes)
  • Firewall allows Syncthing port 22000
  • Mac: System Settings → Network → Firewall off, or allow Syncthing
  • Windows: PowerShell Get-NetFirewallApplicationFilter | ? { $_.Program -match 'syncthing' }

Sync Is Slow

  • Huge folders (tens of thousands of files) — first scan takes long. Folder → Edit → Rescan Interval higher
  • Via internet through Relay → slow. Prefer same LAN
  • Disk I/O bottleneck — SSD recommended

"Out of Sync" Persists

  • Folder → Override Changes (in Send & Receive) — force this machine as master
  • Or Revert Local Changes (Receive mode)
  • Both can lose data; back up first

.stignore Doesn't Take Effect

  • Confirm Use .stignore is checked in Folder → Edit → Ignore Patterns
  • .stignore lives at the folder root (not a subfolder)
  • Trigger Rescan (Folder → ⋮ → Rescan)

Windows Tray Icon Missing

  • winget install may not auto-start
  • The Syncthing Windows Setup installer adds tray + auto-start
  • Or run syncthing.exe --no-console --no-browser on logon via Task Scheduler

Secret Accidentally Synced

  1. Delete the file on both machines immediately
  2. Syncthing can move to trash (Folder → File Versioning)
  3. Rotate the secret itself (API key etc.) — assume the other machine touched it
  4. Add the pattern to .stignore to prevent recurrence

References

Changelog

  • 2026-05-12: First draft. Alternatives + setup (Mac+Win) + five patterns + conflict handling + six troubleshooting cases + .stignore template asset.

Comments