Best Node.js ORMs and ODMs

Best Node.js ORMs and ODMs

This article covers the best and most-used open-source ORM/ODM libraries for Node.js

TypeORM

TypeORM is an ORM (Object Relational Mapping) that allows you to map your JavaScript objects to database tables. It is a TypeScript-first ORM, which means that it uses TypeScript to provide type safety for your database objects.

TypeORM supports a wide range of databases, including MySQL, PostgreSQL, SQLite, and MariaDB. It also supports various other features, such as:

  • Entity and Repository pattern
  • Querying and relationships
  • Data migration
  • Transactions and concurrency control
  • Decorators and metadata
  • Support for TypeScript and JavaScript

Here are some examples of how to use:

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;
}

This code creates a TypeScript class that represents a user in the database. The class is annotated with the @Entity() decorator, which tells TypeORM that this class represents a database table. The @PrimaryGeneratedColumn() decorator tells TypeORM that the id property is the primary key of the table. The @Column() decorator tells TypeORM that the name and email properties are columns in the table.

Once you have created your database objects, you can perform CRUD (Create, Read, Update, Delete) operations on the database. For example, to create a new user, you would use the following code:

const user = new User();
user.name = 'John Doe';
user.email = 'johndoe@example.com';

await user.save();

For more information, please refer to the TypeORM documentation.


Mongoose

Mongoose is an Object Document Mapper (ODM) that allows you to map your JavaScript objects to MongoDB documents. It is a popular ODM for Node.js, and it provides a lot of features, such as:

  • Schema definition
  • Object modeling
  • Querying and population
  • Middleware and hooks
  • Data validation
  • Integration with Express

Here are some examples of how to use:

const mongoose = require('mongoose');

// Create a schema for a user document
const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  age: Number,
});

// Create a model based on the schema
const User = mongoose.model('User', userSchema);

// Create a new user
const user = new User({
  name: 'John Doe',
  email: 'johndoe@example.com',
  age: 30,
});

// Save the user to the database
await user.save();

This code creates a new User object and saves it to the database.

Here is an example of how to use Mongoose to create a relation between documents:

const postSchema = new mongoose.Schema({
  title: String,
  body: String,
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
  },
});

const User = mongoose.model('User', userSchema);
const Post = mongoose.model('Post', postSchema);

// Create a new post
const post = new Post({
  title: 'My first post',
  body: 'This is my first post.',
  author: user.id,
});

// Save the post to the database
await post.save();

This code creates a new Post object and saves it to the database. The author property of the Post object is a reference to the User document that created the post.

Here is an example of how to use Mongoose to perform queries on the database:

// Find all users who are older than 30 years old
const users = await User.find({ age: { $gt: 30 } });

// Find the first post that was created by the user with the ID 12345
const post = await Post.findOne({ author: 12345 });

These are just a few examples of how to use Mongoose. For more information, please refer to the Mongoose documentation.


Sequelize

Sequelize is an Object Relational Mapper (ORM) that allows you to map your JavaScript objects to database tables. It is a popular ORM for Node.js, and it supports a wide range of databases, including MySQL, PostgreSQL, SQLite, Oracle, and Microsoft SQL Server.

Sequelize provides a number of features, such as:

  • Model and migration system
  • Querying and associations
  • Data validation and hooks
  • Transactions and migrations
  • Raw SQL support.

Here are some examples of how to use:

// Import dependencies
const Sequelize = require('sequelize');

// Create a new Sequelize instance
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

// Define the User model
const User = sequelize.define('User', {
  firstName: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  lastName: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  email: {
    type: Sequelize.STRING,
    allowNull: false,
    unique: true,
  },
});

// Synchronize the model with the database
User.sync()
  .then(() => {
    console.log('User table created');
  })
  .catch((err) => {
    console.error('Error creating User table:', err);
  });
User.create({
  firstName: 'John',
  lastName: 'Doe',
  email: 'johndoe@example.com',
})
  .then((user) => {
    console.log('New user created:', user.toJSON());
  })
  .catch((err) => {
    console.error('Error creating user:', err);
  });

For more information, please refer to the Sequelize documentation.


Bookshelf.js

Bookshelf.js is an Object Relational Mapper (ORM) for Node.js that is built on top of Knex.js. It is a lightweight ORM that is designed for simplicity. It is easy to use and provides a lot of features, such as:

  • Models and relationships
  • Query builder
  • Data validation and coercion
  • Hooks and events
  • Plugins and extensions

Here are some examples of how to use:

// Import dependencies
const knex = require('knex')({
  client: 'pg',
  connection: {
    host: 'localhost',
    user: 'username',
    password: 'password',
    database: 'database',
  },
});

const bookshelf = require('bookshelf')(knex);

// Define the User model
const User = bookshelf.model('User', {
  tableName: 'users',
});

// Create the "users" table if it doesn't exist
knex.schema
  .createTable('users', (table) => {
    table.increments('id').primary();
    table.string('firstName').notNullable();
    table.string('lastName').notNullable();
    table.string('email').notNullable().unique();
  })
  .then(() => {
    console.log('User table created');
  })
  .catch((err) => {
    console.error('Error creating User table:', err);
  });
User.forge({
  firstName: 'John',
  lastName: 'Doe',
  email: 'johndoe@example.com',
})
  .save()
  .then((user) => {
    console.log('New user created:', user.toJSON());
  })
  .catch((err) => {
    console.error('Error creating user:', err);
  });

For more information, please refer to the Bookshelf.js documentation.


Objection.js

Objection.js is an object-relational mapping (ORM) library for Node.js that provides a lightweight and intuitive way to interact with relational databases. It is built on top of Knex.js, a SQL query builder for Node.js, and aims to simplify database integration by mapping database tables to JavaScript models.

Objection.js provides a number of features, such as:

  • Model and query API
  • Query builder integration
  • Relationships and eager loading
  • Validation and hooks
  • Transactions and migrations
  • Plugin ecosystem

Here are some examples of how to use:

// Import dependencies
const { Model } = require('objection');
const Knex = require('knex');

// Create a new Knex.js instance
const knex = Knex({
  client: 'pg',
  connection: {
    host: 'localhost',
    user: 'username',
    password: 'password',
    database: 'database',
  },
});

// Bind the Knex.js instance to Objection.js
Model.knex(knex);

// Define the User model
class User extends Model {
  static get tableName() {
    return 'users';
  }

  static get jsonSchema() {
    return {
      type: 'object',
      required: ['firstName', 'lastName', 'email'],
      properties: {
        id: { type: 'integer' },
        firstName: { type: 'string' },
        lastName: { type: 'string' },
        email: { type: 'string' },
      },
    };
  }
}
// Create a new user
const createUser = async () => {
  try {
    const newUser = await User.query().insert({
      firstName: 'John',
      lastName: 'Doe',
      email: 'johndoe@example.com',
    });

    console.log('New user created:', newUser);
  } catch (error) {
    console.error('Error creating user:', error);
  }
};

createUser();

For more information, please refer to the Objection.js documentation.


Prisma

Prisma is a modern Object Relational Mapper (ORM) and Object Document Mapper (ODM) for Node.js that is designed to be simple, flexible, and powerful. It supports a wide range of databases, including MySQL, PostgreSQL, SQLite, and MongoDB.

Prisma provides a number of features, such as:

  • Database modeling and schema management
  • Type-safe database access
  • Powerful query capabilities
  • Data migrations and schema evolution
  • Database connectors
  • Real-time data subscriptions
  • Prisma Client

Here are some examples of how to use :

Define your database schema using Prisma's schema definition language (SDL) in prisma/schema.prisma. Here's an example schema for a simple "User" model:

model User {
  id        Int      @id @default(autoincrement())
  firstName String
  lastName  String
  email     String   @unique
}

Generate the Prisma Client:

npx prisma generate

Use Prisma Client in your Node.js application code:

const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient();

// create new User
async function createUser() {
  try {
    const newUser = await prisma.user.create({
      data: {
        firstName: 'John',
        lastName: 'Doe',
        email: 'johndoe@example.com',
      },
    });

    console.log('New user created:', newUser);
  } catch (error) {
    console.error('Error creating user:', error);
  } finally {
    await prisma.$disconnect();
  }
}

createUser();

async function updateUser(userId, data) {
  try {
    const updatedUser = await prisma.user.update({
      where: { id: userId },
      data,
    });

    console.log('Updated user:', updatedUser);
  } catch (error) {
    console.error('Error updating user:', error);
  } finally {
    await prisma.$disconnect();
  }
}

updateUser(1, { firstName: 'Jane' });

async function deleteUser(userId) {
  try {
    const deletedUser = await prisma.user.delete({
      where: { id: userId },
    });

    console.log('Deleted user:', deletedUser);
  } catch (error) {
    console.error('Error deleting user:', error);
  } finally {
    await prisma.$disconnect();
  }
}

deleteUser(1);

For more information, please refer to the Prisma documentation.

Knex.js

Knex.js is a query builder for Node.js that is designed to be flexible, powerful, and easy to use. It supports a wide range of databases, including MySQL, PostgreSQL, SQLite, and MongoDB.

Knex.js provides a number of features, such as:

  • Fluent query building
  • Database-agnostic
  • Schema migrations
  • Connection pooling
  • Raw SQL support
  • Query execution and result handling

Here are some examples of how to use:

/ Import Knex dependency
const knex = require('knex');

// Create a new Knex instance
const db = knex({
  client: 'pg',
  connection: {
    host: 'localhost',
    user: 'username',
    password: 'password',
    database: 'database',
  },
});

const createRecord = async () => {
  try {
    const newRecord = await db('table_name').insert({
      column1: 'value1',
      column2: 'value2',
    });

    console.log('New record created:', newRecord);
  } catch (error) {
    console.error('Error creating record:', error);
  } finally {
    // Close the database connection
    db.destroy();
  }
};

createRecord();

const updateRecord = async (recordId, newData) => {
  try {
    const numUpdated = await db('table_name')
      .where('id', '=', recordId)
      .update(newData);

    console.log('Updated records:', numUpdated);
  } catch (error) {
    console.error('Error updating record:', error);
  } finally {
    // Close the database connection
    db.destroy();
  }
};

updateRecord(1, { column1: 'new_value1' });

const deleteRecord = async (recordId) => {
  try {
    const numDeleted = await db('table_name')
      .where('id', '=', recordId)
      .del();

    console.log('Deleted records:', numDeleted);
  } catch (error) {
    console.error('Error deleting record:', error);
  } finally {
    // Close the database connection
    db.destroy();
  }
};

deleteRecord(1);

For more information, please refer to the Knex documentation.