lix
README.mdfrom opral/lix
View on GitHub

Lix

Version control system for every file format

weekly downloads on NPM Discord GitHub Stars X (Twitter)

Lix tracks, reviews, branches, merges, and rolls back changes across Markdown, DOCX, XLSX, JSON, PDFs, and custom file formats.

Use Lix standalone or as the change-control backend for editors, knowledge bases, AI workflows, and file-based products. Lix stores files, tracks semantic changes, exposes history through SQL, and brings version control workflows beyond source code.

  • ๐Ÿ“Œ Supports any file format. Create drafts, branches, checkpoints, and releases for Markdown, DOCX, XLSX, JSON, PDFs, and custom formats.
  • ๐Ÿ” Track semantic changes. See the paragraph, cell, property, clause, or custom entity that changed.
  • ๐Ÿ”€ Review and merge changes. Build change proposals, accept/reject flows, rollback, and merge workflows around files.
  • ๐Ÿค Sync in real time. Keep versions and changes in sync across users, agents, devices, and runtimes.
  • โœ… Validate and automate. Run checks, enforce rules, and trigger workflows when files change.
  • ๐Ÿง  Query everything with SQL. Ask what changed, where, when, and by whom without rereading whole files.

Try a demo app

Flashtype is a Markdown editor for Claude and Codex built on Lix. Open local Markdown files, let agents edit them, review changes as diffs, and restore previous versions from history.

Flashtype app preview

Getting started

JavaScript JavaScript ยท Python Python ยท Rust Rust ยท Go Go

npm install @lix-js/sdk
import { openLix, SqliteBackend } from "@lix-js/sdk";

const lix = await openLix({
  backend: new SqliteBackend({ path: "app.lix" }),
});

await lix.execute(
  "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
  ["/notes/status.txt", new TextEncoder().encode("draft")],
);

const main = await lix.activeBranchId();

const draft = await lix.createBranch({ name: "Explore" });

await lix.switchBranch({ branchId: draft.id });

await lix.execute(
  "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
  ["/notes/status.txt", new TextEncoder().encode("ready for review")],
);

await lix.switchBranch({ branchId: main });

const changes = await lix.execute(
  "SELECT schema_key, count(*) AS count FROM lix_change GROUP BY schema_key",
);

Why Lix?

Version control should not stop at source code.

Most version control systems assume source code and text diffs. But many important products edit files where the useful change is a paragraph, spreadsheet cell, JSON property, PDF section, knowledge-base page, or custom entity.

Lix is built for those files. Plugins translate file updates into semantic changes that can be queried, reviewed, branched, merged, and rolled back.

Flashtype, a Markdown editor for Claude and Codex, uses Lix so every local Markdown edit can be checkpointed, reviewed as a diff, and restored.

How does Lix compare to Git? โ†’

What Lix provides

Import as a library

Import Lix and open it inside your worker, service, CLI, browser, desktop app, or server-side runtime. No daemon, no protocol.

import { openLix, SqliteBackend } from "@lix-js/sdk";

const lix = await openLix({
  backend: new SqliteBackend({ path: "app.lix" }),
});

ACID transactions

Write files, blobs, and history in one transaction.

const tx = await lix.beginTransaction();

try {
  await tx.execute(
    "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
    ["/spec.docx", body],
  );
  await tx.execute(
    "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
    ["/spec.png", image],
  );
  await tx.commit();
} catch (error) {
  await tx.rollback();
  throw error;
}

Parallel branches

Give every draft, user, tool, or AI agent its own isolated branch.

const main = await lix.activeBranchId();

const copy = await lix.createBranch({ name: "Copy draft" });
const pricing = await lix.createBranch({ name: "Pricing draft" });
const qa = await lix.createBranch({ name: "QA draft" });

await lix.switchBranch({ branchId: copy.id });
await lix.execute(
  "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
  ["/landing.md", copyDraft],
);

await lix.switchBranch({ branchId: pricing.id });
await lix.execute(
  "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
  ["/plans.json", priceModel],
);

await lix.switchBranch({ branchId: qa.id });
await lix.execute(
  "INSERT INTO lix_file (path, data) VALUES ($1, $2) ON CONFLICT (path) DO UPDATE SET data = excluded.data",
  ["/checks/report.json", testRun],
);

await lix.switchBranch({ branchId: main });

Semantic changes

Lix can track structured entities: XLSX rows, DOCX clauses, JSON properties, app records, custom entities, and more.

const changes = await lix.execute(`
  SELECT created_at, schema_key, entity_pk, snapshot_content
  FROM lix_change
  ORDER BY created_at DESC
  LIMIT 20
`);

For example, a workflow edits an orders spreadsheet:

Before:
| order_id | product  | status  |
| -------- | -------- | ------- |
| 1001     | Widget A | shipped |
| 1002     | Widget B | pending |

After:
| order_id | product  | status  |
| -------- | -------- | ------- |
| 1001     | Widget A | shipped |
| 1002     | Widget B | shipped |

A text-based diff can only tell you the file changed:

-Binary files differ

Lix can expose the row field that changed:

order_id 1002 status:

- pending
+ shipped

Read more about semantic changes โ†’

SQL interface

Answer version-control questions with SQL instead of whole-file rereads.

Claude Code asks: Which orders changed status in this branch? Executing SQL
const rows = await lix.execute(`
  SELECT created_at, schema_key, entity_pk, snapshot_content
  FROM lix_change
  ORDER BY created_at DESC
  LIMIT 20
`);

Every change, across every file and every branch, is a row in lix_change. Filter by branch, file, schema, or time without re-reading whole files.

Portable runtimes and storage

Use Lix standalone or plug it into the infrastructure your product already runs.

SQLite SQLite ยท Postgres Postgres ยท S3 S3 ยท Cloudflare Workers Cloudflare Workers ยท Supabase Supabase

const lix = await openLix({
  backend: new SqliteBackend({ path: "app.lix" }),
});

How Lix works

Lix runs in-process inside your runtime.

It owns the version-control model: files, blobs, versions, history, transactions, and semantic changes. Use it standalone or plug it into whatever backend you need: in-memory, SQLite, Postgres, S3, Cloudflare, or your own adapter.

SQL is the query interface on top. Products, scripts, and agents can ask what changed without rereading whole files.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  Your runtime                   โ”‚
โ”‚       browser ยท desktop ยท server ยท CLI ยท worker  โ”‚
โ”‚                                                 โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                  Lix                    โ”‚   โ”‚
โ”‚   โ”‚  Filesystem ยท Versions ยท History ยท SQL  โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                        โ”‚                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Backend                      โ”‚
โ”‚      SQLite, Postgres, S3, Cloudflare, custom   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Read more about Lix architecture โ†’

Learn More

License

MIT