SQLite Driver
SQLite migration driver with automatic table recreation for limited ALTER TABLE support
Capabilities
| Feature | Supported |
|---|---|
| Native enums | No (CHECK constraint) |
| Native arrays | No (JSON) |
| Index types | btree only |
| Locking | File-based |
| Transactions | Full support |
Type Mappings
| VibORM Scalar | SQLite Type |
|---|---|
string() |
TEXT |
int() |
INTEGER |
bigint() |
INTEGER |
float() |
REAL |
boolean() |
INTEGER (1/0) |
datetime() |
TEXT (ISO 8601) |
json() |
JSON |
blob() |
BLOB |
uuid() |
TEXT |
enumScalar() |
TEXT + CHECK constraint |
| Array scalars | JSON |
Auto-Increment
SQLite uses INTEGER PRIMARY KEY for auto-increment:
const User = model("users", {
id: int().primaryKey().autoIncrement(),
});
Generates:
CREATE TABLE "users" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT
);
Boolean Handling
SQLite stores booleans as integers:
const User = model("users", {
isActive: boolean().default(true),
});
Generates:
CREATE TABLE "users" (
"isActive" INTEGER NOT NULL DEFAULT 1
);
Values: 1 for true, 0 for false.
Enum Handling
SQLite doesn’t have native enums, so VibORM uses TEXT columns with CHECK constraints for validation:
const User = model("users", {
status: enumScalar(["active", "inactive", "pending"]),
});
Generates:
CREATE TABLE "users" (
"status" TEXT CHECK("status" IN ('active', 'inactive', 'pending')) NOT NULL
);
Enum Operations
Adding enum values: Requires table recreation to update the CHECK constraint.
Removing enum values: Requires table recreation to update the CHECK constraint. You must also handle existing data with the removed values.
Dropping an enum: Converts the column to plain TEXT (removes CHECK constraint) via table recreation.
Array Handling
Arrays are stored as JSON:
const User = model("users", {
tags: string().array(),
scores: int().array(),
});
Generates:
CREATE TABLE "users" (
"tags" JSON NOT NULL,
"scores" JSON NOT NULL
);
Values are JSON-encoded: ["tag1", "tag2"] or [100, 200, 300].
Supported Direct Operations
These operations work directly in SQLite:
| Operation | SQLite Version | DDL |
|---|---|---|
| Add column | 3.0+ | ALTER TABLE ... ADD COLUMN |
| Drop column | 3.35.0+ | ALTER TABLE ... DROP COLUMN |
| Rename column | 3.25.0+ | ALTER TABLE ... RENAME COLUMN |
| Rename table | All | ALTER TABLE ... RENAME TO |
| Create index | All | CREATE INDEX |
| Drop index | All | DROP INDEX |
Table Recreation
For operations SQLite doesn’t support natively, VibORM uses table recreation:
Operations Requiring Recreation
- Alter column (type, nullability, default changes)
- Add/drop foreign key
- Add/drop primary key
- Alter/drop enum (updating CHECK constraints)
These operations rewrite the whole table (create a new table, copy the data across, drop the old one, rename, recreate indexes) — slow on large tables. Renamed columns are mapped to their new names during the copy, new columns get their defaults, and dropped columns are excluded.
DDL Examples
Create Table with Enum
CREATE TABLE "users" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"role" TEXT CHECK("role" IN ('admin', 'user', 'guest')) NOT NULL,
"tags" JSON,
"created_at" TEXT DEFAULT (datetime('now'))
);
Add Column
ALTER TABLE "users" ADD COLUMN "bio" TEXT;
Rename Column
ALTER TABLE "users" RENAME COLUMN "name" TO "full_name";
Drop Column
ALTER TABLE "users" DROP COLUMN "bio";
Limitations
| Limitation | Workaround |
|---|---|
| No native enums | CHECK constraints |
| No native arrays | JSON storage |
| Single index type | Only btree available |
| Limited ALTER TABLE | Table recreation |
| No concurrent writes | File-level locking |
Querying JSON Arrays
Querying JSON arrays requires SQLite’s JSON functions:
-- Check if array contains value
SELECT users.*
FROM users, json_each(users.tags)
WHERE json_each.value = 'admin';
LibSQL / Turso
The SQLite driver also works with LibSQL (Turso). The same limitations and features apply.