JSON-first queries
Describe reads, writes, and relation mutations with plain objects instead of opaque builder chains.
jsorm is a JSON-first ORM for TypeScript focused on clarity, strong typing, and explicit SQL behavior. Instead of builder chains or decorator metadata, you describe intent with plain objects — the ORM converts them through a structured AST into parameterized SQL.
Describe a query with a plain object:
import { jsorm } from 'jsorm';
const users = await jsorm.get(User, { select: { id: true, name: true, role: { name: true }, }, where: { active: true, role: { name: { eq: 'admin' } }, }, orderBy: [{ name: 'asc' }], pagination: { perPage: 10, currentPage: 1 },});// Typed as: Array<{ id: number; name: string; role: { name: string } }>The ORM turns that into a structured AST and emits parameterized SQL through the configured adapter. No string interpolation. No magic joins. No hidden eager loading.
JSON-first queries
Describe reads, writes, and relation mutations with plain objects instead of opaque builder chains.
AST-based SQL generation
The internal query structure stays inspectable and versioned before it becomes SQL. Inspect via query.ast.
Type inference from models
defineModel() is the single source of truth for both TypeScript types and runtime metadata — no separate schema files.
Explicit relation builders
belongsTo, hasOne, hasMany, and manyToMany define exact SQL behavior up front. Nothing is implicitly loaded.
Optional migrations
Connect to an existing database immediately. Opt into the migration runtime only when you need schema lifecycle management.
Modular adapters
PostgreSQL, MySQL, SQLite, or a custom pool adapter. The core has zero DB driver dependencies.
defineModel() → JSON query object ↓ normalize + validate ↓ structured AST (inspectable) ↓ Rust engine → SQL generation ↓ parameterized SQL + params ↓ adapter executes + maps rows ↓ typed result (inferred from model)TypeScript backends
Model-driven type inference that matches your database schema — no codegen step.
Explicit SQL teams
Prefer predictable SQL over magic eager loading? jsorm makes every join visible in the query object.
Multi-adapter projects
PostgreSQL, MySQL, SQLite, or custom pools — swap adapters without touching query code.
Existing databases
Drop jsorm onto an existing schema with zero migration ceremony.
@Entity() / @Column() style.jsorm.transaction() hooks but does not implicitly begin/commit.