# Objection.js — SQL-Friendly ORM for Node.js Built on Knex > A full-featured object-relational mapper for Node.js that builds on top of Knex.js, providing a powerful query builder, eager loading, graph inserts, and JSON Schema validation. ## Install Save as a script file and run: # Objection.js — SQL-Friendly ORM for Node.js Built on Knex ## Quick Use ```bash npm install objection knex pg ``` ```javascript const { Model } = require('objection'); const Knex = require('knex'); const knex = Knex({ client: 'pg', connection: 'postgres://localhost/mydb' }); Model.knex(knex); 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' } } }; } } const people = await Person.query().withGraphFetched('pets'); ``` ## Introduction Objection.js is an ORM for Node.js that embraces SQL rather than hiding it. Built on top of the Knex.js query builder, it adds model classes, relations, eager loading, and lifecycle hooks while keeping the full power of SQL accessible. Objection supports PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL. ## What Objection.js Does - Defines models as JavaScript classes with typed relations (HasOne, HasMany, ManyToMany, BelongsToOne) and JSON Schema validation - Provides eager loading via `withGraphFetched` and `withGraphJoined` for loading related models in a single query or with joins - Supports graph inserts and upserts that persist an entire object graph with nested relations in one operation - Exposes the underlying Knex.js query builder for raw SQL, subqueries, and complex joins when needed - Handles transactions, lifecycle hooks (beforeInsert, afterFind, etc.), and model instance methods ## Architecture Overview Objection.js sits as a thin layer on top of Knex.js. Models extend the `Model` base class and declare a `tableName` and optional `relationMappings`. When a query is executed, Objection builds a Knex query, runs it against the database, and hydrates the results into model instances. Eager loading can use either separate queries per relation (withGraphFetched) or SQL joins (withGraphJoined). The query builder is chainable and returns model instances by default, but can return plain objects when needed. Schema validation uses JSON Schema via the ajv library, running before insert and update operations. ## Self-Hosting & Configuration - Install objection, knex, and a database driver (pg, mysql2, better-sqlite3) via npm - Initialize Knex with a connection config and bind it to the Model base class with `Model.knex(knex)` - Define model classes with `tableName`, `relationMappings`, and optionally `jsonSchema` for validation - Use Knex migrations (`knex migrate:make` and `knex migrate:latest`) to manage database schema changes - Configure connection pooling in the Knex configuration for production environments ## Key Features - SQL-first philosophy: every query method maps to understandable SQL, with full access to raw expressions - Graph operations (graphInsert, graphUpsert) that persist deeply nested object trees in a single call - JSON Schema-based validation that runs automatically on insert and update - Multiple eager loading strategies: separate queries for simplicity or joins for performance - Full TypeScript support with typed models, queries, and relation definitions ## Comparison with Similar Tools - **Sequelize** — more abstracted ORM with its own query language; Objection stays closer to SQL and offers better TypeScript support - **TypeORM** — decorator-based ORM inspired by Hibernate; Objection uses plain class definitions and is more SQL-transparent - **Prisma** — schema-first with code generation; Objection is code-first and does not require a separate schema file - **Knex.js** — the query builder Objection is built on; Objection adds models, relations, and validation on top - **MikroORM** — Data Mapper pattern with Unit of Work; Objection uses Active Record-style queries with a SQL-first approach ## FAQ **Q: Should I use withGraphFetched or withGraphJoined?** A: Use `withGraphFetched` (separate queries) for most cases as it avoids row duplication. Use `withGraphJoined` when you need to filter or order by a related model's columns. **Q: Does Objection.js support transactions?** A: Yes. Use `Model.transaction()` to wrap multiple queries in a database transaction with automatic commit and rollback. **Q: Can I use raw SQL with Objection.js?** A: Yes. Use `raw()` expressions in queries, or drop down to the Knex instance directly for fully custom SQL. **Q: Is Objection.js still maintained?** A: Yes. Objection.js receives maintenance updates and has a stable API. The author considers it feature-complete, so releases focus on bug fixes and compatibility. ## Sources - https://github.com/Vincit/objection.js - https://vincit.github.io/objection.js --- Source: https://tokrepo.com/en/workflows/asset-6152d704 Author: Script Depot