Why OKModel
What one schema gives you, what it will not do, and the plain facts that back it.
You describe each table once, in one schema() call, and get typed queries and reviewed migration SQL from it. Calls that would read a whole table or change every row by accident are refused: a bare find() is refused until you set limits in connect, and an update or delete with no where is refused unless you call .all(reason). Tenancy, keeping each customer's rows apart in one database, is declared on the schema too. The package has no runtime dependencies.
What you get
| You get | Where it is shown |
|---|---|
| One schema for types, queries, and migrations | How it works, First schema |
Typed calls on each table (find, one, insert, …) | Queries |
Reviewed migration SQL generated from the schema, and okm check to report drift, a live database that no longer matches the schema | First migration, Drift |
A bare find() refused until you pass limit or .all(reason), or set limits in connect | Query limits |
An update or delete with no where refused unless you call .all(reason) | First schema |
| Tenant isolation declared on the schema | Tenant isolation |
| No runtime dependencies; each driver is an optional peer | Installation |
With no limits in connect, this read is refused before any SQL is sent:
import { connect } from "okmodel/pg/postgresjs";
import { schema, table, t } from "okmodel/pg";
const notes = table("notes", {
id: t.identity().primaryKey(),
title: t.text(),
});
const app = schema({ tables: [notes] });
export async function read(url: string) {
await using db = connect(url, { schema: app });
// Without limits on connect, this throws OKM1101.
await db.notes.find({ where: { id: "1" } });
}OkmError: find() needs a limit.What it will not do
| It will not | Why, and what you do instead |
|---|---|
| Support a database other than PostgreSQL | The schema and the runtime use PostgreSQL features directly, such as row-level security, distinct on, and transaction settings, and every release is tested on PostgreSQL 15 to 18. A dialect, the SQL one database speaks, is written only for PostgreSQL. (Compatibility) |
| Run on Deno | The test suites run on Node.js and Bun only, so no claim is made for Deno. Use Node.js 22.18+ or Bun 1.4+. (Installation) |
| Set a default read limit by itself | Without limits, a find with no limit is refused. Pass limits to connect to choose the defaults. (Query limits) |
| Ship a driver inside the package | The package has no runtime dependencies, so installing it adds nothing besides the driver you choose. Install the peer your runtime already uses. (Drivers) |
Plain facts
| Fact | Detail |
|---|---|
| PostgreSQL | Majors 15, 16, 17, and 18 (Minimum Postgres) |
| Runtimes | Node.js 22.18 or newer; Bun 1.4 or newer (CLI, Drivers) |
| Drivers in the conformance table | postgres.js, node-postgres, Bun.sql, and PGlite (Compatibility) |
| Neon | Supported as okmodel/pg/neon; not a column in that table (Drivers) |
| Deno | Unsupported (Installation) |
The conformance table lists the drivers that pass the shared driver test suites: the same queries, errors, and transactions checked against each driver. okm driver test <driver> runs those suites (driver test).