knex vs sequelize vs pg-promise vs bookshelf
Node.js ORM Libraries
knexsequelizepg-promisebookshelfSimilar Packages:
Node.js ORM Libraries

Node.js ORM Libraries are tools that help developers interact with databases using object-oriented programming principles. They provide an abstraction layer over the database, allowing developers to perform CRUD (Create, Read, Update, Delete) operations using JavaScript objects instead of writing raw SQL queries. This approach improves code readability, maintainability, and security by preventing SQL injection attacks. Popular Node.js ORM libraries include Sequelize, TypeORM, and Mongoose, each offering unique features and capabilities for different types of databases and applications.

Npm Package Weekly Downloads Trend
3 Years
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
knex2,661,00820,169874 kB7022 years agoMIT
sequelize2,147,69030,3112.91 MB1,0039 months agoMIT
pg-promise561,8213,547417 kB12 months agoMIT
bookshelf81,0676,365-2376 years agoMIT
Feature Comparison: knex vs sequelize vs pg-promise vs bookshelf

Database Support

  • knex:

    knex supports a wide range of SQL databases, including PostgreSQL, MySQL, SQLite, and Oracle. It is highly versatile and can be used with any SQL-compliant database.

  • sequelize:

    sequelize supports multiple SQL databases, including PostgreSQL, MySQL, MariaDB, SQLite, and Microsoft SQL Server. It provides a unified API for working with different database dialects.

  • pg-promise:

    pg-promise is specifically designed for PostgreSQL, offering deep integration with PostgreSQL features and capabilities. It is not suitable for other database types.

  • bookshelf:

    bookshelf supports multiple databases through Knex.js, including PostgreSQL, MySQL, and SQLite. However, it does not provide native support for NoSQL databases.

Query Building

  • knex:

    knex offers a powerful and flexible query building API that allows for programmatic construction of SQL queries. It supports chaining, raw queries, and provides fine-grained control over the generated SQL.

  • sequelize:

    sequelize provides a high-level query API that abstracts away much of the SQL complexity. It supports chaining, raw queries, and includes features like pagination and filtering out of the box.

  • pg-promise:

    pg-promise allows for both programmatic query building and raw SQL execution. It provides a flexible API for creating dynamic queries, but it does not include a built-in query builder like Knex.

  • bookshelf:

    bookshelf provides a simple and intuitive query building interface, leveraging Knex.js under the hood. It allows for easy creation of complex queries, but it is not as flexible as Knex for low-level query manipulation.

Migrations

  • knex:

    knex includes a powerful migration and seeding tool as part of the package. It provides a CLI for creating and running migrations, making it easy to manage database schema changes.

  • sequelize:

    sequelize includes a built-in migration and seeding system, complete with a CLI for creating and running migrations. It also supports migration rollback and versioning.

  • pg-promise:

    pg-promise does not provide built-in migration tools, but it can be integrated with third-party migration libraries like node-pg-migrate or db-migrate for schema management.

  • bookshelf:

    bookshelf does not include a built-in migration tool, but it can be easily integrated with Knex.js migrations, allowing for schema management and versioning.

Associations

  • knex:

    knex does not provide built-in support for associations, as it is primarily a query builder. However, associations can be implemented manually in the application logic or by using additional libraries.

  • sequelize:

    sequelize provides robust support for associations, including one-to-one, one-to-many, and many-to-many relationships. It offers a rich API for defining and managing associations, including eager and lazy loading.

  • pg-promise:

    pg-promise does not have built-in support for associations, but it allows for manual implementation of relationships in the database and application code. It provides flexibility for handling related data as needed.

  • bookshelf:

    bookshelf supports various types of associations, including one-to-one, one-to-many, and many-to-many. It provides a simple API for defining and working with relationships between models.

Ease of Use: Code Examples

  • knex:

    knex Example:

    const knex = require('knex')({
      client: 'pg',
      connection: {
        host: 'localhost',
        user: 'user',
        password: 'password',
        database: 'mydb'
      }
    });
    
    // Query example
    knex('users').where({ id: 1 }).first().then(user => {
      console.log(user);
    });
    
  • sequelize:

    sequelize Example:

    const { Sequelize, DataTypes } = require('sequelize');
    const sequelize = new Sequelize('postgres://user:password@localhost:5432/mydb');
    
    // Define a model
    const User = sequelize.define('User', {
      name: { type: DataTypes.STRING },
      email: { type: DataTypes.STRING },
    });
    
    // Fetch a user
    User.findByPk(1).then(user => {
      console.log(user.toJSON());
    });
    
  • pg-promise:

    pg-promise Example:

    const pgp = require('pg-promise')();
    const db = pgp({
      host: 'localhost',
      user: 'user',
      password: 'password',
      database: 'mydb'
    });
    
    // Query example
    db.one('SELECT * FROM users WHERE id = $1', 1)
      .then(user => {
        console.log(user);
      });
    
  • bookshelf:

    bookshelf Example:

    const Bookshelf = require('bookshelf');
    const knex = require('knex')({
      client: 'pg',
      connection: {
        host: 'localhost',
        user: 'user',
        password: 'password',
        database: 'mydb'
      }
    });
    
    const bookshelf = Bookshelf(knex);
    
    // Define a model
    const User = bookshelf.model('User', {
      tableName: 'users',
    });
    
    // Fetch a user
    User.where({ id: 1 }).fetch().then(user => {
      console.log(user.toJSON());
    });
    
How to Choose: knex vs sequelize vs pg-promise vs bookshelf
  • knex:

    Choose knex if you need a flexible and powerful SQL query builder that supports multiple database dialects. It is not an ORM but provides a robust foundation for building complex queries programmatically while allowing for raw SQL when needed.

  • sequelize:

    Choose sequelize if you need a full-featured ORM with support for multiple database dialects, including PostgreSQL, MySQL, and SQLite. It offers a rich set of features, including migrations, associations, and a powerful query API, making it suitable for complex applications.

  • pg-promise:

    Choose pg-promise if you are working specifically with PostgreSQL and need a feature-rich library that supports advanced PostgreSQL features, transactions, and query formatting. It is highly customizable and provides excellent performance for PostgreSQL applications.

  • bookshelf:

    Choose bookshelf if you prefer a lightweight ORM that follows the Active Record pattern and provides a simple API for working with related data. It is built on top of Knex.js, making it a good choice if you are already using Knex for query building.

README for knex

knex.js

npm version npm downloads Coverage Status Dependencies Status Gitter chat

A SQL query builder that is flexible, portable, and fun to use!

A batteries-included, multi-dialect (PostgreSQL, MySQL, CockroachDB, MSSQL, SQLite3, Oracle (including Oracle Wallet Authentication)) query builder for Node.js, featuring:

Node.js versions 12+ are supported.

You can report bugs and discuss features on the GitHub issues page or send tweets to @kibertoad.

For support and questions, join our Gitter channel.

For knex-based Object Relational Mapper, see:

To see the SQL that Knex will generate for a given query, you can use Knex Query Lab

Examples

We have several examples on the website. Here is the first one to get you started:

const knex = require('knex')({
  client: 'sqlite3',
  connection: {
    filename: './data.db',
  },
});

try {
  // Create a table
  await knex.schema
    .createTable('users', (table) => {
      table.increments('id');
      table.string('user_name');
    })
    // ...and another
    .createTable('accounts', (table) => {
      table.increments('id');
      table.string('account_name');
      table.integer('user_id').unsigned().references('users.id');
    });

  // Then query the table...
  const insertedRows = await knex('users').insert({ user_name: 'Tim' });

  // ...and using the insert id, insert into the other table.
  await knex('accounts').insert({
    account_name: 'knex',
    user_id: insertedRows[0],
  });

  // Query both of the rows.
  const selectedRows = await knex('users')
    .join('accounts', 'users.id', 'accounts.user_id')
    .select('users.user_name as user', 'accounts.account_name as account');

  // map over the results
  const enrichedRows = selectedRows.map((row) => ({ ...row, active: true }));

  // Finally, add a catch statement
} catch (e) {
  console.error(e);
}

TypeScript example

import { Knex, knex } from 'knex';

interface User {
  id: number;
  age: number;
  name: string;
  active: boolean;
  departmentId: number;
}

const config: Knex.Config = {
  client: 'sqlite3',
  connection: {
    filename: './data.db',
  },
};

const knexInstance = knex(config);

try {
  const users = await knex<User>('users').select('id', 'age');
} catch (err) {
  // error handling
}

Usage as ESM module

If you are launching your Node application with --experimental-modules, knex.mjs should be picked up automatically and named ESM import should work out-of-the-box. Otherwise, if you want to use named imports, you'll have to import knex like this:

import { knex } from 'knex/knex.mjs';

You can also just do the default import:

import knex from 'knex';

If you are not using TypeScript and would like the IntelliSense of your IDE to work correctly, it is recommended to set the type explicitly:

/**
 * @type {Knex}
 */
const database = knex({
  client: 'mysql',
  connection: {
    host: '127.0.0.1',
    user: 'your_database_user',
    password: 'your_database_password',
    database: 'myapp_test',
  },
});
database.migrate.latest();