27 March 2023 (updated: 19 December 2024)

Mongoose vs Typegoose in NestJS

Chapters

      After you choose the MongoDB database in your system, you’ll probably also use an ODM library. The most popular is Mongoose or a library built on top of it - Typegoose. In this article, we’ll cover their main differences when working specifically with the NestJS framework.

      You probably already know that Typegoose is essentially a way to use Mongoose with TypeScript and that would be your criteria when choosing the library. But it’s a bit more to this when working with the NestJS framework because there is a Mongoose wrapper created by NestJS authors - @nestjs/mongoose and when You look at the syntax - it seems almost identical to Typegoose.

      Let’s break down the differences between them so it’s easier to decide what approach you should choose in your project - using @nestjs/mongoose package or Typegoose. When integrating MongoDB with a NestJS application, you’ll find examples and code snippets demonstrating how to set up a NestJS application to work with MongoDB using TypeScript and packages like Typegoose.

      Main differences

      Connection and model injection with MongoDB database

      @nestjs/mongoose is a library dedicated to the Nest framework so it comes with full support of its DI workflow. On the other hand, Typegoose can be used in any other NodeJS project so you will have to either integrate it with Nest on your own or use community packages.

      Schema definition

      Although both packages allow defining schemas using similar decorators, their interfaces vary and Typegoose provides more options than the Nest wrapper. For example - `@Schema()` decorator takes only Mongoose’s defined schema options, whereas `@modelOptions()` in addition to this offers access to an existing connection and some custom Typegoose configuration options.

      With `@nestjs/mongoose`, if you want to manually modify the schema definition based on the metadata, you can use the `DefinitionsFactory` class. This approach can be useful when it’s difficult to represent everything using decorators.

      Class methods

      Both packages allow defining instances and static methods. Here are examples on how we can define class methods in both packages:

      As you can see, we have to create additional interfaces when using mongoose, Typegoose however allows us to get type information from classes. The definitions are also more natural as they are contained within a class like regular methods. With the Nest package, you have to use the `statics` and `methods` properties outside of the class, which slightly reduces readability and becomes a less natural approach when it comes to using classes.

      Hooks

      Both packages support hooks. In @nestjs/mongoose you can use them in the factory method of module imports. Typegoose offers support with @pre() and @post() decorators.

      Custom query methods

      You can add custom queries in both packages, but you will probably encounter type issues in Mongoose. The difference between a query method and a static function on the model is that the function would not be chainable

      Virtuals

      Virtual properties can be created in Typegoose using ES6 get & set functions, whereas with the Nest package you have to use the `virtual` property outside of the class, which similarly to class methods, feels less natural to work with.

      Which one should you choose?

      Although Mongoose already can infer types from schema definition and its Nest wrapper has cool features you’ll still benefit more when using Typegoose. It also has better documentation and community support. The question is - do you have the time and resources to integrate Typegoose into your Nest project? If so, I’d personally give it a chance.

      Check out also

      Paweł Sierant

      Backend Developer

      Maybe it’s the beginning of a beautiful friendship?

      We’re available for new projects.

      Contact us