Skip to content

Introduction

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.

  • Browser / edge runtimes — jsorm requires the Rust engine binary (server-only).
  • Decorator-based entities — prefer TypeORM or MikroORM for @Entity() / @Column() style.
  • Auto-managed transactions — jsorm exposes jsorm.transaction() hooks but does not implicitly begin/commit.