Smuggler

Five minutes to your first push.

Four steps. Real commands. Nothing hidden.

Install smugglr, point it at a local SQLite file and a Cloudflare D1 target, dry-run the push to see what would change, then push. If you already know Workers, the Cloudflare quickstart is even shorter.

1. Install.

Cargo is the recommended install. Pre-built binaries and a one-line installer script are on the GitHub releases page.

  cargo install smugglr

Confirm it works:

  smugglr --version

2. Configure.

Create a config.toml in your project directory. The minimal config is four lines: where the local SQLite lives, what the target is, and the target's connection details.

  [source]
path = "./local.db"

[target]
type = "d1"
database = "my-database"
account_id = "your-cloudflare-account-id"
api_token = "your-d1-api-token"

Any SQLite file works for source.path. The target can be d1, turso, rqlite, datasette, starbasedb, or sqlite-cloud. See the Configuration reference for every option.

3. Dry-run.

See what the push would do before doing it. Dry-run reads both sides, hashes, diffs, and reports. Nothing is written.

  smugglr push --dry-run

The output tells you how many rows would push per table and whether they are new or updated. Run this as many times as you like. It is safe.

4. Push.

When the dry-run looks right, drop the flag.

  smugglr push

smugglr pushes only the rows that actually changed, batched to respect the target's per-request SQL parameter limit. Transient HTTP failures retry with exponential backoff. Exit code 0 means success.

What Next.

Watch daemon.

Background sync on a fixed interval. Set it and forget it.

watch reference

Stash and retrieve.

S3-compatible relay for machines that cannot reach each other directly.

stash reference

Full docs.

CLI reference, configuration, internals, and nine usage patterns.

docs hub