Why DriftSync runs no code: moving data, not commands

The DriftSync team

EngineeringSafety

DriftSync moves data, not code. That one design decision is why you can point it at a live production site without holding your breath — and it’s the clearest line between DriftSync and the migration tools that apply changes by running a command.

Executing steps on a live site is the risk

Plenty of config-migration tools work by executing something on the target: a shell command, a PHP hook, a WP-CLI step baked into the transfer. When that step runs on production, you are trusting a process you can’t easily read to do exactly the right thing — and to do nothing else. If it half-completes, or assumes a state your site isn’t in, you find out after it has already touched the live site.

That’s not a hypothetical edge case; it’s the normal failure mode of “run this to sync it.” The command is opaque, the blast radius is the whole environment, and the undo story is usually “restore a backup and hope.”

A bundle is data you can read

DriftSync’s unit of sync is a config bundle: plain, human-readable JSON. It is never PHP, JavaScript or shell, so there is nothing in it that can execute. It is only values, applied to settings. You can open it, read every line, and diff it — the same way you’d review any other change.

Because it’s just text, a bundle fits the workflow you already trust: commit it to git, attach it to a pull request, let a teammate review it. The thing you’re about to apply is fully legible before it goes anywhere near production.

The dry-run diff shows you exactly what apply does

Before DriftSync writes anything, it shows a dry-run diff: a field-by-field comparison of what’s on the target now versus what the bundle would set. Reviewing it writes nothing, so it’s always safe to run.

text
blogname            overwrite   "Acme (staging)"  →  "Acme"
timezone_string     add         —                 →  "Europe/London"
sidebar_widgets     merge       3 items           →  +1 item
mailchimp_api_key   held        (redacted)        →  (fill in on target)
active_theme        skip        "acme-child"      (unchanged: not in bundle)

Every value carries a status — add, overwrite, merge, held or skip — so “what will this do to the live site?” has a concrete answer before you approve it, not a shrug.

Secrets are held, not blanked

Configuration is full of things you don’t want to ship: API keys, SMTP passwords, environment URLs. On export DriftSync scans for them and holds them — it withholds the value rather than writing it into the file. A held value stays out of the bundle entirely, so committing that JSON to git doesn’t leak a secret.

Important

Held is not the same as blank. When you apply a bundle with a held field, DriftSync leaves the target’s existing value in place — it does not overwrite the real key with an empty string. The secret that already lives on production keeps working. See secrets and redaction.

Every apply is reversible

Reading a change beforehand handles the “did I mean to do this?” question. Snapshots handle the “can I undo it?” one. DriftSync captures a restore point automatically, right before every apply, and records the apply in History. If a change lands wrong, you roll back in a single click — no backup archaeology. See snapshots and rollback.

An honest contrast

To be fair about it: a premium incumbent that applies changes through a command or shell step isn’t “broken.” It works, and people ship with it every day. The difference is where the risk sits. A step that executes on the target is opaque and hard to reverse; a bundle of data that you reviewed in a diff, with a snapshot behind it, is neither. DriftSync deliberately gives up the ability to run arbitrary steps in exchange for a change you can read and undo.

We lay this out side by side — WPChangeSync’s command step included — on the compare page. And the whole loop is free on WordPress.org; direct connections, the team library and DriftSync Cloud come with Pro.


← Back to blog