diff --git a/AGENTS.md b/AGENTS.md
index aafe4a0..5bf3397 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -56,4 +56,3 @@ This package converts Pro Cycling Manager CDB binary database files to and from
## References
- API usage and examples: [README.md](README.md)
-- Build/export behavior note: [build-notes.md](memories/repo/build-notes.md)
diff --git a/README.md b/README.md
index 94fb2ca..96c3348 100644
--- a/README.md
+++ b/README.md
@@ -36,8 +36,8 @@ The conversion is **lossless**: a full `cdb → sqlite → cdb` round-trip prese
- **CLI included** — convert files without writing any code; direction is auto-detected.
- **Lossless round-trip** — table flags, column order, and data types survive an export/reopen cycle.
- **Optional relational schema** — reconstruct `PRIMARY KEY` / `FOREIGN KEY` constraints for JOINs and ER diagrams, without breaking the round-trip.
-- **Isomorphic** — runs in Node.js and in the browser via [sql.js](https://github.com/sql-js/sql.js).
-- **Lightweight** — the library's own code is ~28 kB, with only `pako` and `sql.js` as dependencies.
+- **Node-first, browser-capable** — the CLI and default `better-sqlite3` engine target Node.js; an optional `sql.js` (WASM) engine covers the browser.
+- **Lightweight** — the library's own code is ~28 kB. `better-sqlite3` is a hard dependency; the `sql.js` (WASM) engine is optional and installed separately.
- **TypeScript-first** — native type definitions and full IDE support.
- **Tree-shakeable** — pure functions, no side effects, ESM + CommonJS builds.
@@ -48,7 +48,7 @@ npm install cdb-converter
```
> [!NOTE]
-> Requires **Node.js 22 or newer**. In the browser, `sql.js` loads its WebAssembly runtime on demand.
+> Requires **Node.js 22 or newer**. The CLI and the default `better-sqlite3` engine are ready to use out of the box — `better-sqlite3` is installed automatically as a dependency. For the browser, install `sql.js` instead — it loads its WebAssembly runtime on demand.
The fastest way to try it is the CLI:
@@ -83,10 +83,10 @@ npx cdb-converter --version
| `.cdb` | CDB → SQLite | `.sqlite` |
| `.sqlite` / `.db` | SQLite → CDB | `.cdb` |
-| Option | Effect |
-| ------------------- | -------------------------------------------------------------------------------------------------- |
+| Option | Effect |
+| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `-n`, `--normalize` | (CDB → SQLite only) reconstruct PK/FK constraints from PCM naming conventions. See [Normalized schema](#normalized-schema). |
-| `--index-fk` | Implies `--normalize`; also indexes every FK column for faster JOINs (roughly doubles output size). |
+| `--index-fk` | Implies `--normalize`; also indexes every FK column for faster JOINs (roughly doubles output size). |
## Library usage
@@ -94,14 +94,12 @@ npx cdb-converter --version
```typescript
import fs from "node:fs";
-import initSqlJs from "sql.js";
+import { betterSqlite3Engine } from "cdb-converter/engines/better-sqlite3";
import { cdbToSql } from "cdb-converter";
-const SQL = await initSqlJs();
-
// Read and convert a CDB file
const cdbBuffer = fs.readFileSync("save.cdb");
-const db = cdbToSql(cdbBuffer, SQL);
+const db = cdbToSql(cdbBuffer, betterSqlite3Engine);
// Query it like any SQLite database
const result = db.exec("SELECT * FROM Teams LIMIT 5");
@@ -112,14 +110,14 @@ fs.writeFileSync("save.sqlite", db.export());
```
> [!IMPORTANT]
-> You must pass the initialized `sql.js` module returned by `initSqlJs()`. This library does not initialize `sql.js` for you: that setup is asynchronous and environment-specific (the caller decides how the wasm file is loaded in Node.js or the browser).
+> You must pass a `SqlEngine`. `cdb-converter/engines/better-sqlite3` (requires the `better-sqlite3` package) is the default for Node.js; `cdb-converter/engines/sql-js` (requires the `sql.js` package) works in the browser but needs an `await` to initialize its WASM runtime. See [Using a different SQLite engine](#using-a-different-sqlite-engine).
### Normalized schema
By default the SQLite output is a flat mirror of the CDB tables, with no relational constraints. Pass `{ normalize: true }` to reconstruct `PRIMARY KEY` and `FOREIGN KEY` constraints from the PCM naming conventions (`ID{table}` identity columns and `fkID{target}` references), turning the export into a proper relational database — ready for JOINs, entity-relationship diagrams, and schema introspection tools.
```typescript
-const db = cdbToSql(cdbBuffer, SQL, { normalize: true });
+const db = cdbToSql(cdbBuffer, betterSqlite3Engine, { normalize: true });
// Relationships are now navigable:
db.exec(`
@@ -138,24 +136,25 @@ Notes:
```typescript
// Lean: constraints only (~+40% size)
-cdbToSql(cdbBuffer, SQL, { normalize: true });
+cdbToSql(cdbBuffer, betterSqlite3Engine, { normalize: true });
// Heavier, faster JOINs: also index FK columns (~2x size)
-cdbToSql(cdbBuffer, SQL, { normalize: true, indexForeignKeys: true });
+cdbToSql(cdbBuffer, betterSqlite3Engine, {
+ normalize: true,
+ indexForeignKeys: true,
+});
```
### SQLite to CDB
```typescript
import fs from "node:fs";
-import initSqlJs from "sql.js";
+import { betterSqlite3Engine } from "cdb-converter/engines/better-sqlite3";
import { sqlToCdb } from "cdb-converter";
-const SQL = await initSqlJs();
-
// Load a SQLite database and convert back to CDB
const sqliteBuffer = fs.readFileSync("save.sqlite");
-const db = new SQL.Database(sqliteBuffer);
+const db = new betterSqlite3Engine.Database(sqliteBuffer);
const cdbBuffer = sqlToCdb(db); // automatically compressed
fs.writeFileSync("save.cdb", Buffer.from(cdbBuffer));
@@ -178,8 +177,9 @@ const decompressed = decompressCdb(compressed); // accepts compressed or raw inp