Skip to content

Why MountSQLI?

MountSQLI is built on five principles. Each one is a decision that trades away some convenience for safety, size, or speed.

The builder is a typed view over SQL, not a replacement for it. When you write where("email", "=", x), you are writing SQL — just checked by TypeScript.

// This is SQL. You can read it.
db.from(users).where("age", ">", 18).orderBy("createdAt", "desc");
// → SELECT * FROM "users" WHERE "age" > ? ORDER BY "createdAt" DESC

Why it matters: you never outgrow the abstraction. Anything SQL can do, the builder can express — and when it can’t, the guarded raw-SQL helpers can.

If a query can be checked at compile time, it is. Wrong column? Wrong operator? Wrong nullability? Those are type errors, not runtime crashes.

db.from(users).where("emial", "=", "x");
// ^^^^ Type error: no column named "emial"

Why it matters: bugs that would reach production in other ORMs fail at tsc.

Queries are data (QueryPlan), not objects with methods mutating this. The builder is immutable and shares structure between copies. There is no per-row object graph on the read path.

Why it matters: MountSQLI tree-shakes to the features you use and runs on edge runtimes where allocation budgets are tight.

No code generators, no decorators, no bespoke schema language. Your schema is plain TypeScript, and types are inferred from it.

const users = defineTable("users", { id: int().pk(), email: text().notNull() });
type User = InferTable<typeof users>; // { id: number; email: string }

Why it matters: nothing to run before you code. No prisma generate step.

Any AI-generated SQL or code goes through the same compiler validator as your hand-written input. The ai package turns natural language into a QueryPlan, not a raw string.

Why it matters: generated queries are type-checked and injection-safe, just like yours.

Every public API is measured against its Prisma/Drizzle/TypeORM equivalent. If a feature is not shorter or safer, it does not ship.