Introduction
MasterRecord is the ORM half of Master. You describe your tables as plain classes, it generates and runs migrations, and you query with a fluent, lambda-based language — the same code across SQLite, MySQL, and PostgreSQL.

Two styles, one ORM#
MasterRecord supports both the Active Record style (entities save themselves — great for getting started) and the Entity Framework style (a change-tracked context with saveChanges() — efficient for batch work). Use whichever fits the moment.
DbContext, a MasterRecord context is scoped per request — with MasterController that is master.addScoped('db', AppContext) and this.db in controllers. Never share one module-level context across requests. See Change Tracking & Context Lifetime.Code-first models#
Each field is a method that receives the schema builder. MasterRecord reads these to build your tables — no separate schema file, no decorators.
// app/models/Post.js — fields are methods on the class
export default class Post {
id(db) { db.integer().primary().auto(); }
title(db) { db.string().notNullable(); }
body(db) { db.text(); }
views(db) { db.bigint(); }
created_at(db) { db.datetime(); }
}title(db) { db.string(); }, not this.title = {...}. The builder reads prototype methods; plain instance properties are ignored. See Defining Models.An expressive query language#
Queries use real JavaScript lambdas with $$ placeholders for safe, parameterized values — no string concatenation, no injection.
import db from './app/models/db.js';
// Create (Active Record style)
const post = db.Post.new();
post.title = 'By the power of Grayskull';
await post.save();
// Read with a parameterized query
const found = await db.Post
.where((p) => p.title.like($$), 'By the power%')
.toList();
// Update
found[0].views = 9000;
await found[0].save();What’s in the box#
MasterRecord 1.22 deliberately mirrors Entity Framework Core — the EF concept is named next to each feature so you can map your existing knowledge straight across.
- Code-first models with a fluent field builder; TPH inheritance, composite keys, owned JSON types, computed columns, SQL defaults, check constraints, FK constraints with
ON DELETE. - Change tracking as a unit of work — identity map, dirty index,
asNoTracking()/asTracking(),entry(), request-scoped contexts andContextPool(EFDbContext,AddDbContextPool). - Query language —
where,and,like,any, ordering, pagination, aggregates,groupBy().aggregate(),executeUpdate/executeDelete, named global query filters. - Relationships —
belongsTo,hasMany,hasOne,hasManyThrough,manyToManyskip navigations; include / thenInclude / asSplitQuery, explicit and lazy loading. - Transactions & concurrency —
transaction(), savepoints,rowVersion()/concurrencyToken()withConcurrencyError, retry on transient failures, save events. - Migrations — schema diffing, atomic apply with a tracking table,
script,migrations-status,remove-migration; full CLI reference. - Transformers, lifecycle hooks, pluggable logging with parameter redaction, health checks.
- Query caching (in-memory or Redis) and full-text search.