An SQL-friendly ORM for Node.js built on Knex.js with powerful query building, relationship handling, and JSON Schema validation
npx @tessl/cli install tessl/npm-objection@3.1.0Objection.js is an SQL-friendly ORM for Node.js built on top of Knex.js. It provides powerful query building capabilities, robust relationship handling, JSON schema validation, and graph operations while maintaining full SQL power and flexibility.
npm install objection knexconst { Model, QueryBuilder, transaction, raw, ref, fn } = require('objection');For ES modules:
import { Model, QueryBuilder, transaction, raw, ref, fn } from 'objection';TypeScript:
import { Model, QueryBuilder, transaction, raw, ref, fn } from 'objection';const { Model } = require('objection');
const Knex = require('knex');
// Initialize knex
const knex = Knex({
client: 'sqlite3',
connection: { filename: './database.sqlite' }
});
// Bind knex to Model
Model.knex(knex);
// Define a model
class Person extends Model {
static get tableName() {
return 'persons';
}
static get relationMappings() {
return {
pets: {
relation: Model.HasManyRelation,
modelClass: Pet,
join: {
from: 'persons.id',
to: 'pets.ownerId'
}
}
};
}
}
// Use the model
const person = await Person.query()
.insert({ firstName: 'John', lastName: 'Doe' });
const people = await Person.query()
.withGraphFetched('pets')
.where('age', '>', 18);Objection.js is built around several key components:
Model class for defining database entities with validation and relationshipsCore model functionality for defining database entities, validation, and basic CRUD operations.
class Model {
static get tableName(): string;
static get idColumn(): string | string[];
static get jsonSchema(): object;
static get relationMappings(): object;
static query(trx?: Transaction): QueryBuilder;
static fromJson(json: object, options?: ModelOptions): Model;
$query(trx?: Transaction): QueryBuilder;
$id(id?: any): any;
$toJson(options?: ToJsonOptions): object;
}Advanced query building with chainable methods, joins, aggregates, and complex WHERE conditions.
class QueryBuilder {
select(...columns: string[]): QueryBuilder;
where(column: string, operator: string, value: any): QueryBuilder;
join(table: string, leftCol: string, rightCol: string): QueryBuilder;
orderBy(column: string, direction?: 'asc' | 'desc'): QueryBuilder;
insert(data: object | object[]): QueryBuilder;
update(data: object): QueryBuilder;
delete(): QueryBuilder;
withGraphFetched(expression: string): QueryBuilder;
}Relationship definitions and eager loading patterns for efficient data fetching.
// Relation types
const HasOneRelation: RelationType;
const HasManyRelation: RelationType;
const BelongsToOneRelation: RelationType;
const ManyToManyRelation: RelationType;
const HasOneThroughRelation: RelationType;
interface RelationMapping {
relation: RelationType;
modelClass: typeof Model;
join: {
from: string;
to: string;
through?: object;
};
}Relationships and Eager Loading
Insert, update, and upsert operations for complex nested data structures with relationship handling.
insertGraph(graph: object | object[], options?: InsertGraphOptions): QueryBuilder;
upsertGraph(graph: object | object[], options?: UpsertGraphOptions): QueryBuilder;
interface InsertGraphOptions {
relate?: boolean | string[];
allowRefs?: boolean;
}
interface UpsertGraphOptions {
relate?: boolean | string[];
unrelate?: boolean | string[];
insertMissing?: boolean | string[];
update?: boolean | string[];
noInsert?: boolean | string[];
noUpdate?: boolean | string[];
noDelete?: boolean | string[];
}Database transaction management with model binding and automatic rollback.
function transaction<T>(
callback: (trx: Transaction) => Promise<T>
): Promise<T>;
function transaction<T>(
knex: Knex,
callback: (trx: Transaction) => Promise<T>
): Promise<T>;Query expression builders for raw SQL, column references, values, and functions.
function raw(sql: string, ...bindings: any[]): RawBuilder;
function ref(expression: string): ReferenceBuilder;
function val(value: any): ValueBuilder;
function fn(functionName: string, ...args: any[]): FunctionBuilder;JSON Schema validation system and comprehensive error types for database constraints.
class ValidationError extends Error {
statusCode: number;
data: object;
type: string;
}
class NotFoundError extends Error {
statusCode: number;
type: 'NotFound';
}
class AjvValidator {
constructor(config: AjvConfig);
validate(args: ValidatorArgs): object;
}Utility functions for column mapping, mixins, and extending model functionality.
function snakeCaseMappers(options?: SnakeCaseMappersOptions): ColumnNameMappers;
function knexSnakeCaseMappers(options?: SnakeCaseMappersOptions): KnexMappers;
function mixin(modelClass: typeof Model, ...plugins: Plugin[]): typeof Model;
function compose(...plugins: Plugin[]): Plugin;type Transaction = Knex.Transaction;
type RelationExpression = string | object;
type MaybeCompositeId = string | number | Array<string | number>;
interface ModelOptions {
patch?: boolean;
skipValidation?: boolean;
}
interface ToJsonOptions {
virtuals?: boolean | string[];
shallow?: boolean;
}
interface QueryContext {
transaction?: Transaction;
[key: string]: any;
}