scratch-sync

Sync private scratch/ folders across machines using Syncthing over Tailscale

What It Does

Many developers use a scratch/ folder in their repos for notes, experiments, and work-in-progress that shouldn't be in git but should sync across their machines.

scratch-sync uses Syncthing to sync these folders peer-to-peer over your Tailscale network — no cloud storage, no configuration hell.

Cross-Platform

Works on macOS, Linux, and Windows with native installers.

Private & Secure

Peer-to-peer sync over Tailscale. No cloud relay, no third parties.

Zero Config

Auto-discovers Tailscale peers. One command to pair devices.

Git-Friendly

Works with your existing .gitignore. scratch/ stays local.

┌─────────────────┐ Tailscale ┌─────────────────┐ │ Linux Box │◄──────────────────►│ Mac Laptop │ │ ~/code/sleap-io │ │ ~/sleap-io │ │ └── scratch/ │ folder-id: │ └── scratch/ │ │ │ "scratch-sleap-io"│ │ └────────┬────────┘ └────────┬────────┘ │ Tailscale │ └──────────────┬───────────────────────┘ ▼ ┌─────────────────┐ │ Windows PC │ │ D:\sleap-io │ │ └── scratch/ │ └─────────────────┘

The key insight: Syncthing folder IDs just need to match across devices. The actual filesystem paths can be completely different.

Install

Before installing, make sure you have Tailscale installed and connected on all machines you want to sync.

1. Install Syncthing

curl -LsSf https://scratch.tlab.sh/install.sh | sh
iwr -useb https://scratch.tlab.sh/install.ps1 | iex

This downloads Syncthing and sets it up as a background service. Want to inspect the script first? Run curl -LsSf https://scratch.tlab.sh/install.sh | less

2. Install the CLI

The CLI requires uv. Install globally:

uv tool install scratch-sync

Or run without installing:

uvx scratch-sync --help

Update: uv tool upgrade scratch-sync  |  Uninstall: uv tool uninstall scratch-sync

Quick Start

On each machine

cd ~/code/my-project
scratch-sync init

Then pair your devices

scratch-sync pair

The pair command discovers all Syncthing instances on your Tailscale network and pairs them automatically. Once paired, scratch/ folders sync whenever devices have matching folder IDs.

CLI Reference

scratch-sync init

Initialize scratch-sync in a git repository. Adds the scratch/ folder to Syncthing.

scratch-sync init [PATH] [--name NAME]
Argument Description
PATH Path to the git repository (default: current directory)
--name, -n Custom name for the sync folder (default: repo name)

What it does:

  1. Finds or creates the scratch/ directory
  2. Adds it to Syncthing with folder ID scratch-{reponame}
  3. Adds all known Syncthing devices to the folder
  4. Creates a default .stignore file
  5. Adds scratch/ to .gitignore if not already present

scratch-sync pair

Discover and pair with other devices running scratch-sync on your Tailscale network.

scratch-sync pair [--timeout SECONDS]
Option Description
--timeout, -t Discovery timeout in seconds (default: 3.0)

What it does:

  1. Gets all online peers from your Tailscale network
  2. Queries each peer's Syncthing REST API
  3. Discovers Syncthing device IDs automatically
  4. Pairs devices bidirectionally
  5. Adds discovered devices to all existing scratch folders

scratch-sync status

Show the current sync status of all scratch-sync managed folders.

scratch-sync status

scratch-sync list

List all scratch-sync managed folders.

scratch-sync list

Advanced

Installer Options

macOS / Linux:

Option Description
--status Show dependency status without installing
--uninstall Remove Syncthing and the auto-start service
--upgrade Upgrade to the latest Syncthing version
-y, --yes Skip confirmation prompts

Windows (set before running iwr | iex):

Variable Description
$env:STATUS=1 Show dependency status without installing
$env:UNINSTALL=1 Remove Syncthing and scheduled task
$env:ALLUSERS=1 Install as Windows service (requires admin)

Dashboard Setup

Important: After installation, set up a password for the Syncthing dashboard at http://127.0.0.1:8384/

Go to Actions > Settings > GUI and set a username and password.

Direct Syncthing Commands

scratch-sync is a wrapper around Syncthing. For advanced use:

syncthing cli config folders list
syncthing cli config devices list
syncthing cli show folder-status scratch-my-project
syncthing cli operations scan --folder scratch-my-project
syncthing cli config folders remove --id scratch-my-project

Troubleshooting

Syncthing not in PATH:

export PATH="$HOME/.local/bin:$PATH"

Service not starting (Linux):

systemctl --user status syncthing
journalctl --user -u syncthing -f
systemctl --user start syncthing

Service not starting (macOS):

launchctl list | grep syncthing
tail -f ~/Library/Logs/syncthing.log
launchctl load ~/Library/LaunchAgents/com.syncthing.syncthing.plist