Skip to content

Repository files navigation


CI Release License Dolt Bun

One binary. One connection string change. Your database, versioned like code.

DATABASE_URL=mysql://root@127.0.0.1:3307/repo — that's the whole migration.


InstallQuick startWorkflowCommandsArchitecture


deltix status        # 50ms — what changed?
deltix commit -m "add email column"
deltix push          # team is up to date
deltix quick start — init → start → status deltix status — staged vs unstaged deltix branch — create → checkout → list Drizzle + Deltix — migrate → status → commit

Isolated demos — no sensitive data, repo demo-hello in /tmp, re-record with vhs assets/tapes/*.tape.


Why Deltix

Without Deltix With Deltix
mysqldump > dump.sql → Drive → Slack → mysql < dump.sql (overwrites) deltix pushdeltix pull (merges)
No branches. Copy DB to appdb_test to try. deltix branch create feature + deltix checkout — isolated
No diff. SHOW CREATE TABLE by eye. deltix diff — row + schema diff
No history. Restore backup from 3 days ago. deltix log + checkout <hash>

Features

Branch & merge — for real feature-emails with tags does not exist on main until merge. Fast-forward, per-cell conflicts. Validated with Drizzle.

50ms feedback loop status via MySQL wire (mysql2 to :3307), not dolt spawn. Was 6s on Windows.

Diff without server deltix diff shows dolt diff --stat locally. No from/to needed for working tree.

Git-like, not Git status → staged vs unstaged (dolt_status), commit -m, push/pull, log -n 5.


Install

OS Command
Linux / macOS
curl -fsSL https://raw.githubusercontent.com/SammyBytes/Deltix-Client/main/scripts/get-deltix-client.sh | bash
# → ~/.local/bin/deltix
Windows
irm https://raw.githubusercontent.com/SammyBytes/Deltix-Client/main/scripts/get-deltix-client.ps1 | iex
# → $HOME\.local\bin\deltix.exe
Any
# from latest release — no Bun needed
chmod +x deltix-linux-x64 && sudo mv deltix-linux-x64 /usr/local/bin/deltix
deltix version

First command that needs Dolt downloads the pinned 2.3.1 binary to ~/.deltix/bin/ and verifies SHA-256 — you never install a DB yourself.


Quick start

A. New project from scratch

deltix init myapp && deltix start   # Dolt on 127.0.0.1:3307
# .env
DATABASE_URL=mysql://root@127.0.0.1:3307/myapp

# create tables with your ORM — Drizzle, Prisma, SeaORM, whatever
bun run db:migrate
deltix status        # → users new table (unstaged)
deltix commit -m "init schema"
deltix push

B. Adopt an existing MySQL

deltix init myapp --from mysql://root@127.0.0.1:3306/myapp   # once
# or: deltix import myapp --from mysql://root@127.0.0.1:3306/myapp
deltix push          # ships schema + data

# switch the app — one line
DATABASE_URL=mysql://root@127.0.0.1:3307/myapp  # was :3306

--continue skips bad rows (NOT NULL, type coercion), --schema-only / --no-commit for preview, --blobs base64|skip for BLOBs. DSN without password prompts masked.


Workflow — the daily loop

graph LR
  A[App on :3307<br/>Drizzle/Prisma] -->|ALTER TABLE| B[Dolt working tree]
  B -->|deltix status 50ms| C{unstaged?}
  C -->|deltix commit| D[local commit]
  D -->|deltix push| E[Deltix-Server :9090]
  E -->|deltix pull| F[teammates on :3307]
  B -.->|deltix branch| G[feature/* isolated]
  G -.->|deltix merge| D
Loading
# feature branch — 100% deltix, no dolt needed
deltix branch create myapp feature-emails
deltix checkout feature-emails

# change via ORM
bun run db:migrate

deltix status          # On branch feature-emails / users modified
deltix diff            # 1 Row Added (local)
deltix commit -m "add email column"

deltix checkout main   # isolation: main has 4 users, feature has 5
deltix merge myapp feature-emails   # fast-forward
deltix push

Commands

Setup & auth
Command What it does
deltix configure One-time setup (server URL, TLS, local port). Saved to ~/.deltix/config.json.
deltix login <user> Masked prompt. --password= or $DELTIX_LOGIN_PASSWORD for scripts (warns).
deltix logout / whoami End / show session.
deltix version Client + server (/status with TLS).
Local — git-like
Command What it does
deltix init <repo> Bind folder to repo (.deltix/ + local Dolt repo).
deltix start [<repo>] Start dolt sql-server on :3307. Persists port, fails fast if busy, adopts orphans.
deltix stop / status Stop / show running + branch + staged vs unstaged (wire 50ms).
deltix checkout <branch> [<repo>] Global checkout — stop → dolt checkout → start so app + CLI share branch.
deltix commit <msg> [tables...] dolt add -A + commit (author = logged-in user).
deltix branch list/create/checkout/delete/current Local-first (falls back to local when server has no repo). branch local lists both.
`deltix diff [ [ ]]`
deltix merge [<repo>] <src> [target] Local merge (fast-forward/conflicts), falls back from server.
deltix log [<repo>] Server log. -n / --branch supported, flags before repo too.
Server / sync
Command What it does
deltix repo create/list/get Provision / list repos.
deltix push [<repo>] Send unpushed commits (schema DDL + CSV rows via dolt table import).
deltix pull [<repo>] Fetch + merge origin/main. --abort to abort conflicts.
deltix fetch Update origin/* without touching branch.
deltix roles / sync-prefs Per-repo ACL and sync scope.

Git integration

deltix pairs your data with your code — it does not replace git and does not fire git hooks. Its local versioning lives in Dolt (a database that versions itself like git), so deltix commit / push / pull do not go through git, even when run inside an existing git repo — they are two independent versioning tracks that coexist in the same working tree.

Artifact What it is Does git see it?
.deltix/config.toml Project binding (deltix init), the analog of .git/config Yes, as an untracked file
~/.deltix/ Local Dolt repos + client config (outside the tree) No (lives in the home dir)
.dolt/ Data Dolt repo (outside the working tree) No

The one rule you must respect

When you run deltix init inside a code git repo, add .deltix/ to your .gitignore:

# .gitignore
.deltix/

Otherwise a plain git add . would drag the local Deltix binding into your code repo by accident (the binding varies per machine and should not travel via git). Your data — the Dolt repos — already live outside the working tree under ~/.deltix/, so only the project-root .deltix/config.toml is what you need to ignore.

Optional hooks (example)

Since deltix does not trigger git hooks, if you want your data pushed automatically whenever you git commit / git push code, create the hook yourself. Example post-commit:

# .git/hooks/post-commit  (create the file and `chmod +x .git/hooks/post-commit`)
deltix push   # runs from the repo dir, resolves the project automatically

You can do the same with post-merge (refresh data after a git pull). For push automation across all your projects, set a global hooks dir:

git config --global core.hooksPath ~/.git-hooks
# then write the hook at ~/.git-hooks/post-commit and make it executable

Warning: hooks run on every commit of every project using that core.hooksPath. A silently failing deltix push could slow you down, and a deltix push when there is nothing to push is wasted work. Prefer a per-repo hook, or gate it behind "only run when there is something to send".


Architecture

cli/        → parsing + delegation, no logic
  ↓
ports/      → interfaces (DoltSqlPort, LocalRepoPort)
  ↓
core/       → pure functions (table-name, csv)
adapters/   → DoltMysqlAdapter (wire, fast) / DoltCliAdapter (fallback)
contexts/   → stateful orchestration, depends on ports (never adapters directly)

No local DB of its own — Dolt is the DB. No Turso. Adding bun:sqlite later would be BunSQLiteAdapter implements DoltSqlPort, zero context change.

Full rules in .github/copilot-instructions.md — see docs/ARCHITECTURE.md for the one-page version.


Dependencies (automated updates)

Dependabot keeps the project's dependencies patched automatically. It is configured in .github/dependabot.yml and covers:

  • npm — runtime + dev dependencies (zod, mysql2, consola, @biomejs/biome, …), grouped into a single minor-and-patch PR each update.
  • GitHub Actions — pinned action versions (actions/checkout, softprops/action-gh-release, …).
  • Docker — base images.

Handling a Dependabot PR

  1. Open the PR and look at the test CI check.

  2. If the check fails with lockfile had changes, but lockfile is frozen, the bun.lock was not regenerated for the bumped version. Fix it by checking out the PR branch and running bun install, then commit the regenerated bun.lock:

    git fetch origin <dependabot-branch>
    git checkout <dependabot-branch>
    bun install        # updates bun.lock for the new versions
    git add bun.lock && git commit -m "chore(deps): regenerate bun.lock"
    git push origin <dependabot-branch>
  3. Confirm bun run lint exits 0 and bun run test:unit is green on the updated branch, then merge the PR.

Minor/patch bumps are grouped on purpose: they are low-risk and should largely "just work". A pre-release/security-critical bump still lands as its own PR so it can be reviewed and shipped faster.


Stack & security

Engine Dolt 2.3.1 (MySQL wire, branch/merge/diff)
Client Bun 1.4 + TypeScript, consola, mysql2, zod — single binary bun build --compile
Server Bun + Hono REST :9090, JWT Ed25519
Security argv arrays only (no shell), author sanitised [A-Za-z0-9_.-], TLS trust-on-first-use, creds 0600, secrets masked

MIT — see LICENSECHANGELOGSECURITY

DATABASE_URL=:3307 and you are versioned.

About

Single-binary CLI for database version control: import MySQL/MariaDB into a Dolt repo, edit through MySQL or the CLI, then push commits to Deltix-Server with branch/merge/log/diff/audit. v0.7.16, MIT licensed.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages