DEV Community

Cover image for Battle of the Node.js ORMs: Sequelize vs TypeORM
Victor J. Rosario V.
Victor J. Rosario V.

Posted on

Battle of the Node.js ORMs: Sequelize vs TypeORM

Popular Object-Relational Mapping (ORM) libraries for Node.js include Sequelize and TypeORM. Both of these libraries offer a higher level of abstraction over relational databases and simplify database operations by offering a user-friendly API.

While there are numerous parallels across these libraries, there are also significant variances. Some of the most significant distinctions between Sequelize and TypeORM will be discussed in this post.

Language Support

The language support offered by Sequelize and TypeORM is one of their key distinctions. When compared to TypeORM, Sequelize supports TypeScript as well as JavaScript.

Sequelize may therefore be a better option for you if you're working on a JavaScript-based project. However, if you're using TypeScript, TypeORM might be a better choice.

Querying

Another difference between Sequelize and TypeORM is in how they handle queries. Sequelize uses a query builder, which allows you to construct complex queries using JavaScript or TypeScript. On the other hand, TypeORM uses a repository pattern, which allows you to perform basic CRUD (Create, Read, Update, Delete) operations using methods like find, findOne, save, update, and delete.

Both approaches have advantages, however, TypeORM's repository design may be easier to use for simple CRUD operations while Sequelize's query builder mechanism may be better suited for more complex queries.

Relationships

You can specify one-to-many, many-to-many, and one-to-one relationships between tables in your database using both Sequelize and TypeORM. They manage relationships differently, though.

Sequelize defines relationships using a conventional method, in which the foreign key constraint is specified in the migration or model definition. On the other hand, TypeORM employs a more contemporary methodology in which relationships are defined using decorators in your model design.

This indicates that Sequelize might be a better option for you if you want a more conventional way of defining relationships. Nonetheless, TypeORM can be a better choice if you choose a more contemporary strategy.

Support for Other Databases

Their support for different databases is yet another distinction between Sequelize and TypeORM. Despite the fact that both libraries support a variety of databases, Sequelize offers broader support for more databases, such as MySQL, PostgreSQL, SQLite, and Microsoft SQL Server. Contrarily, MySQL, PostgreSQL, MariaDB, SQLite, Oracle, Microsoft SQL Server, and MongoDB are all supported by TypeORM.

This can be a crucial consideration if you're using a particular database that neither library supports.

Sample CRUD using both ORMs

Sequelize Example

Here is an example of how to create a model and carry out CRUD operations on a database table using Sequelize:

const { Sequelize, Model, DataTypes } = require('sequelize');

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

class User extends Model {}
User.init({
  firstName: DataTypes.STRING,
  lastName: DataTypes.STRING,
  email: DataTypes.STRING
}, { sequelize, modelName: 'user' });

(async () => {
  await sequelize.sync();
  const user = await User.create({ firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' });
  console.log(user.toJSON());
  const users = await User.findAll();
  console.log(users.map(user => user.toJSON()));
})();
Enter fullscreen mode Exit fullscreen mode

This code establishes a connection to a MySQL database, defines a User model with three characteristics, synchronizes the model with the database, creates a new user record, retrieves all users from the database, and logs the results to the console.

TypeORM Example

Here's an example of using TypeORM to define a model and perform CRUD operations on a database table:

import { createConnection } from 'typeorm';

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

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column()
  email: string;
}

(async () => {
  const connection = await createConnection();
  const user = new User();
  user.firstName = 'John';
  user.lastName = 'Doe';
  user.email = 'john.doe@example.com';
  await connection.manager.save(user);
  console.log(user);
  const users = await connection.manager.find(User);
  console.log(users);
})();
Enter fullscreen mode Exit fullscreen mode

By creating a new user record, building a User entity with three properties, extracting all users from the database, and logging the results to the console, this application connects to a normal MySQL database.

As you can see, both Sequelize and TypeORM provide similar APIs for defining models/entities and performing CRUD operations on a database table. However, the syntax and approach are different due to the language and design choices made by each library.

Sample relationship table using both ORMs

TypeORM Example

Take the User and Post objects as an example. Each post has a single owner, and each user is permitted to have several posts. Here is how this relationship might be expressed using TypeORM:

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

  @Column()
  name: string;

  @OneToMany(() => Post, post => post.user)
  posts: Post[];
}

@Entity()
class Post {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  content: string;

  @ManyToOne(() => User, user => user.posts)
  user: User;
}
Enter fullscreen mode Exit fullscreen mode

In the User entity, we define a one-to-many relationship with Post using the @OneToMany decorator. We specify that the relationship is to the Post entity and that it's related to the user property on the Post entity.

In the Post entity, we define a many-to-one relationship with User using the @ManyToOne decorator. We specify that the relationship is to the User entity and that it's related to the posts property on the User entity.

With this setup, we can fetch a user and all their posts like this:

const user = await connection.manager.findOne(User, 1, { relations: { posts: true } });
Enter fullscreen mode Exit fullscreen mode

This will fetch the user with the ID of 1 and eagerly load all their posts.

Sequelize Example

Here's how we can define the same relationship using Sequelize:

const { Sequelize, Model, DataTypes } = require('sequelize');

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

class User extends Model {}
User.init({
  name: DataTypes.STRING
}, { sequelize, modelName: 'user' });

class Post extends Model {}
Post.init({
  title: DataTypes.STRING,
  content: DataTypes.STRING
}, { sequelize, modelName: 'post' });

User.hasMany(Post);
Post.belongsTo(User);
Enter fullscreen mode Exit fullscreen mode

In this example, we define the User and Post models using Model.init. We then define the relationship between the two models using the User.hasMany(Post) and Post.belongsTo(User) methods.

With this setup, we can fetch a user and all their posts like this:

const user = await User.findByPk(1, { include: [Post] });
Enter fullscreen mode Exit fullscreen mode

This will fetch the user with the ID of 1 and eagerly load all their posts.

Top comments (1)

Collapse
 
ydanielsb97 profile image
Yeison S

It's pretty interesting and well-developed, my congratulations. In addition to that information, even though both, TypeORM and Sequelize have support for Javascript and Typescript, you can get the best from them in their focused language, which are:

TypeORM = Typescript
Sequelize = Javascript

This could be taken into consideration too to make the right choice.