Two n8n environments drift apart, someone promotes the wrong version by hand, and a client’s automation stops at 2am.

chiral push · dev → prod
$ chiral push --source dev --target prod

  Credential map:
    dev_postgres    → prod_postgres    found
    dev_sendgrid    → prod_sendgrid    found

  + My New Workflow              (will be created)
  + Invoice Sync [DEV]          (will be created as "Invoice Sync")
  ~ Updated Workflow             (active - will be paused briefly)
   Unchanged Workflow           (already up to date - skipped)

    Pushing to prod - review changes above carefully.
? Type "prod" to confirm: prod

   Snapshot saved    → .chiral/snapshots/20240101T120000Z-a3f2b9c1/
   Created  My New Workflow
   Created  Invoice Sync  (mapped from "Invoice Sync [DEV]")
   Updated  Updated Workflow    (reactivated)
   Skipped  Unchanged Workflow  (already up to date)

   Push complete - 2 changes
    Deployment: 20240101T120000Z-a3f2b9c1

  Next: chiral pull --env prod
sh -c "$(curl -sSfL https://chiral.sh/install)"
Get started →

Every import to prod was a guess. You'd find out if it was wrong from the errors.

n8n assigns a new versionId on every save. Chiral diffs the content, so it only flags what actually changed.

chiral diff · dev → prod
Comparing dev → prod

  + New Workflow             (will be created - wrong name? run: chiral workflow map)
  + Invoice Sync [DEV]      (mapped to "Invoice Sync" in prod but not found - does it exist?)
  - Deprecated Workflow      (in prod, not in dev)
  ~ Updated Workflow         (modified - versionId differs)

2 added, 1 modified, 1 removed.
Run 'chiral push --source dev --target prod --dry-run' to preview.
Comparing dev → prod

  + New Workflow             (will be created - wrong name? run: chiral workflow map)
  + Invoice Sync [DEV]      (mapped to "Invoice Sync" in prod but not found - does it exist?)
  - Deprecated Workflow      (in prod, not in dev)
  ~ Updated Workflow         (modified - versionId differs)

2 added, 1 modified, 1 removed.
Run 'chiral push --source dev --target prod --dry-run' to preview.

Same versionId, or a matching content hash after a push, reads as unchanged, and the diff stops crying wolf.

The import looked clean. The workflow ran. The credential wasn't there.

When a remapped credential is missing in the target, the push aborts before touching anything, and prints the exact command to fix it.

chiral push · credential pre-flight
  Credential map:
    dev_postgres    → prod_postgres    found
    dev_sendgrid    → (not mapped)     missing in prod

  Cannot push - 1 credential not found in prod. Create it first or run:
  chiral credential add sendgrid prod=prod_sendgrid
  Credential map:
    dev_postgres    → prod_postgres   ✓ found
    dev_sendgrid    → (not mapped)    ✗ missing in prod

  Cannot push - 1 credential not found in prod. Create it first or run:
  chiral credential add sendgrid prod=prod_sendgrid

Chiral migrates credential names between environments, not their secret values. It refuses rather than push a workflow pointed at a credential that is not there.

The last import wins. There's no warning.

It reads the shared audit log and warns when a teammate pushed to prod after your last pull, before you overwrite their work.

chiral push · concurrency check
    prod was last pushed by alice@example.com 2 hours ago.
     You may be overwriting their changes.
     Run 'chiral diff --source prod --target dev' to check.
? Push anyway? [y/N]:
  ⚠  prod was last pushed by alice@example.com 2 hours ago.
     You may be overwriting their changes.
     Run 'chiral diff --source prod --target dev' to check.
? Push anyway? [y/N]:

Detection runs against .chiral/audit.jsonl. It is a warning, not a hard block: you decide whether to continue.

The import broke it. There was no previous version to restore.

Before touching a single workflow, Chiral snapshots the target. If the push breaks something, you have an exact restore point from before it started.

chiral push · pre-push snapshot
   Created  My New Workflow
   Updated  Billing Pipeline
   Failed   Order Processor    (connection timeout)
   Skipped  (2 remaining - not attempted)

   Push incomplete - 2 of 5 workflows applied.
    Pre-push snapshot saved at .chiral/snapshots/20240101T120000Z-a3f2b9c1/
    Upgrade to the paid tier for one-command rollback, or restore manually from the snapshot.
  ✓ Created  My New Workflow
  ✓ Updated  Billing Pipeline
  ✗ Failed   Order Processor    (connection timeout)
  ─ Skipped  (2 remaining - not attempted)

  ✗ Push incomplete - 2 of 5 workflows applied.
    Pre-push snapshot saved at .chiral/snapshots/20240101T120000Z-a3f2b9c1/
    Upgrade to the paid tier for one-command rollback, or restore manually from the snapshot.

The snapshot is written before the first workflow is touched. One-command rollback is a paid feature; the snapshot itself is always yours.

Four failure modes. All of them silent. None of them recoverable without starting over.

Concept: why it’s called Chiral

Two mirror-image environment graphs Left and right node graphs reflected across a central axis. Every node matches its mirror except one, which is highlighted as the mismatch. staging production
Two environments that should be mirror images of each other, like a molecule’s left and right hands. The one place they fail to match is the bug Chiral exists to catch.

What it is

A command-line tool that promotes n8n workflows between your own environments.

Chiral runs against the n8n REST API on instances you host. It reads both environments, shows you the real diff, takes a snapshot of the target, and applies only what changed. It never deletes a workflow unless you ask, and it stops when a credential is missing.

The free tier covers diff, push, snapshots, and concurrency detection. The paid tier adds one-command rollback, gated pushes, and --delete-removed. Pricing is flat per team, with no per-seat metering and no usage billing.

pricing
  tier   price          notes
  ─────────────────────────────────────────────────────
  free   $0 / forever   diff, push, snapshots, dry-run
  team   $79 / month    + rollback, gated pushes, audit
  ─────────────────────────────────────────────────────
  n8n Source Control: €800/month  ·  Business plan only.
  Chiral runs on CE.
  tier   price          notes
  ─────────────────────────────────────────────────────
  free   $0 / forever   diff, push, snapshots, dry-run
  team   $79 / month    + rollback, gated pushes, audit
  ─────────────────────────────────────────────────────
  n8n Source Control: €800/month  ·  Business plan only.
  Chiral runs on CE.
sh -c "$(curl -sSfL https://chiral.sh/install)"
Read the docs → Full comparison →

Follow CLI releases

Track Chiral releases without polling GitHub.

Feature updates and release notes. No pitch emails. Unsubscribe any time.