Lix is an embeddable version control system you import as a library. Give agents versions, checkpoints, semantic change history, rollback, immutable history, and SQL-queryable context without wrapping Git or managing repo internals.
- Runs in-process. Import it as a library and run it inside your app. No daemon, no protocol.
- ACID transactions. One transaction can cover state, blobs, and history.
- Semantic changes. Track XLSX rows, DOCX clauses, JSON properties, and more as entities.
- SQL interface. Agents can query history and changes without rereading whole files.
- Bring your own backend. Start in memory, then plug into SQLite, Postgres, S3, Cloudflare, or your own adapter.
JavaScript ·
Python ·
Rust ·
Go
npm install @lix-js/sdk better-sqlite3import { openLix } from "@lix-js/sdk";
import { createBetterSqlite3Backend } from "@lix-js/sdk/sqlite";
const lix = await openLix({
backend: createBetterSqlite3Backend({ path: "app.lix" }),
});
const main = await lix.activeVersionId();
await lix.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["orders-file", "/orders.xlsx", bytes],
);
const draft = await lix.createVersion({ name: "Explore" });
await lix.switchVersion({ versionId: draft.id });
await lix.execute(
"UPDATE lix_file SET data = $1 WHERE path = '/orders.xlsx'",
[draftBytes],
);
await lix.switchVersion({ versionId: main });
const merge = await lix.mergeVersion({
sourceVersionId: draft.id,
});
const changes = await lix.execute(
"SELECT schema_key, count(*) AS count FROM lix_change GROUP BY schema_key",
);AI agents are creating explosive demand for version control: isolated workspaces, checkpoints, versions, reviewable changes, and rollback.
Teams reach for Git, but wrapping it means managing repository directories, worktrees, locks, packfiles, garbage collection, LFS, process calls, protocol servers, and transaction coordination around a tool that expects to live outside the app.
Lix is built the other way around: version control runs in-process inside your app.
How does Lix compare to Git? →
Import Lix and open it inside your app. No daemon, no protocol.
import { openLix } from "@lix-js/sdk";
import { createBetterSqlite3Backend } from "@lix-js/sdk/sqlite";
const lix = await openLix({
backend: createBetterSqlite3Backend({ path: "app.lix" }),
});Write files, blobs, and history in one transaction.
const tx = await lix.beginTransaction();
try {
await tx.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["spec-doc", "/spec.docx", body],
);
await tx.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["spec-preview", "/spec.png", image],
);
await tx.commit();
} catch (error) {
await tx.rollback();
throw error;
}Give every agent its own isolated version without creating Git-style multi-checkout worktrees.
const main = await lix.activeVersionId();
const copy = await lix.createVersion({ name: "Copy draft" });
const pricing = await lix.createVersion({ name: "Pricing draft" });
const qa = await lix.createVersion({ name: "QA draft" });
await lix.switchVersion({ versionId: copy.id });
await lix.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["landing", "/landing.md", copyDraft],
);
await lix.switchVersion({ versionId: pricing.id });
await lix.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["plans", "/plans.json", priceModel],
);
await lix.switchVersion({ versionId: qa.id });
await lix.execute(
"INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)",
["qa-report", "/checks/report.json", testRun],
);
await lix.switchVersion({ versionId: main });Unlike Git's line-based diffs, Lix can track structured entities: XLSX rows, DOCX clauses, JSON properties, app records, and more.
const changes = await lix.execute(`
SELECT created_at, schema_key, entity_id, snapshot_content
FROM lix_change
ORDER BY created_at DESC
LIMIT 20
`);For example, an agent 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 |
Git can only tell you the file changed:
-Binary files differLix can expose the row field that changed:
order_id 1002 status:
- pending
+ shippedRead more about semantic changes →
Agents burn fewer tokens and keep cleaner context when version-control questions are answered with SQL instead of whole-file rereads.
const rows = await lix.execute(`
SELECT created_at, schema_key, entity_id, 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.
Start in memory, then plug Lix into the infrastructure your app already runs.
SQLite ·
Postgres ·
S3 ·
Cloudflare Workers ·
Supabase
const lix = await openLix({
backend: createBackend({ url: env.LIX_BACKEND }),
});Lix runs in-process inside your app.
It owns the version-control model: files, blobs, versions, history, transactions, and semantic changes. You plug it into whatever backend you need: in-memory, SQLite, Postgres, S3, Cloudflare, or your own adapter.
SQL is the query interface on top. Agents can ask what changed without rereading whole files.
┌─────────────────────────────────────────────────┐
│ Your runtime │
│ agent worker · server · CLI · app │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Lix │ │
│ │ Filesystem · Versions · History · SQL │ │
│ └────────────────────┬────────────────────┘ │
│ │ │
└────────────────────────┼────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ Backend │
│ SQLite, Postgres, S3, Cloudflare, custom │
└─────────────────────────────────────────────────┘
Read more about Lix architecture →
- AI agent filesystems - isolated workspaces, versioned explore steps, semantic change history, and rollback when a run goes sideways.
- Version control for Postgres & SQLite - time-travel and versioned schemas on top of an existing database. Reviewable migrations. Diffable rows.
- Apps with version control - add versions, review, rollback, and history to editors, CMSs, design tools, internal ops apps, and AI-native products.
- Review for AI-generated changes - surface what an agent actually changed at the entity level. Approve, request edits, or revert by symbol instead of patch.
v0.6: ready to embed (current)
- Importable SDK
- ACID transactions across state, blobs, and history
- Parallel sessions and versions
- Entity-level change tracking, queryable via SQL
- Stable physical storage layout
- Pluggable backend interface
v0.7: CLI
- CLI for creating, inspecting, and scripting Lix repositories
v0.8: file plugin API
- Finalized file plugin API for DOCX, XLSX, CAD, PDF, and code
v0.9: merge conflicts
- Merge conflicts as first-class citizens
v0.10: working changes
- Working changes and checkpointing
- Getting Started Guide - Build your first app with Lix
- Documentation - Full API reference and guides
- Discord - Get help and join the community
- GitHub - Report issues and contribute