The best NestJS Starter Kit for your new NodeJS project

The best NestJS Starter Kit for your new NodeJS project

Choose the best NestJS Boilerplate to get your NodeJS project started faster

When you start the development of a new project on NestJS you have quite a big range of options: starting from scratch or taking one of the multiple boilerplates developed by the community. Starting from scratch is quite a good option if you’d like to have full control of everything in your project and you have some time to set it all up. But if you have tight deadlines (almost always =) ), you can save quite a lot of time by taking one of the pre-setup solutions: boilerplates.

Boilerplate is a starter kit, a set of configured libraries and some basic features, that helps to start the project faster. You can also use a boilerplate just as a reference to see how to build or set up some features or just clone the repository and start your project from it.

In the Awesome NestJS list, I found 32 repositories under the Boilerplate section by the time this article was written. Quite a lot, huh? How would you choose what to take for your next project? I must admit here that we are the authors of one of such boilerplates. But I promise, in this article, we’ll try to be as objective as we can and try to help you to choose what fits you best.

Pre-filter

Before we start, we need to filter those solutions somehow, because analyzing all 32 of them would take way too much time. We are lazy developers, so, better try to find just decent candidates first for our research.

The main criteria will be:

  • Support and Maintenance: if the project is active at all?

  • Production readiness: if the project is ready to be used in production now?

  • Performance

  • Code quality

So finally we chose 5 boilerplates that more or less satisfy our requirements and added them to the table:

StarsContributorsLast Commit DateOpen IssuesApproach
NestJS REST API Boilerplate2.1K16 contributors, most of the code written by 1 developer, supported by Brocoders company26-02-20246REST API
Awesome NestJS Boilerplate2.1K16 contributors, most of the code written by 1 developer05-01-202411REST API
NestJS Prisma Starter2.1K22 contributors, most of the code written by 1 developer17-12-20239GraphQL
Squareboat NestJS Boilerplate63310 contributors, most of the code written by 1 developer07-08-20235REST API
Nest Hackathon Starter3546 contributors, most of the code written by 1 developer24-01-20231REST API

Now we are going to compare them by features.

Features

NestJS REST API BoilerplateAwesome NestJS BoilerplateNestJS Prisma StarterSquareboat NestJS BoilerplateNest Hackathon Starter
Documentation+Legacy++-
Sign in / Sign up+++-+
Social sign in+----
Roles+++--
Confirm email+---+
Forgot password+----
Config Service+++--
Mailing+--++
Translations++-+-
Database+ (PostgreSQL + TypeORM or MongoDB)+ (PostgreSQL, TypeORM)+ (PostgreSQL, Prisma)+ (Knex)+ (PostgreSQL, Prisma)
Migrations+++++
Seeding+-++-
File uploadLocal, AWS S3, Can extendAWS S3, Can not extend---
Tests+++++
CIE2E tests, linterLinterUnit tests--
Swagger+++-+
Docker+++--
Auto updating dependencies+---+ (But without tests. It can break the build)
💡
The main advantage of the NestJS REST API Boilerplate by Brocoders is complementary frontend React Boilerplate that works seamlessly with this backend: Extensive React Boilerplate.

Code Review

Here I will briefly take a look into the repositories and give my notes about the source code of each selected repository. I would say that I didn’t find any critical issues, just a few things that make sense to keep in mind. Hopefully, this code review can help you to avoid some common mistakes in your projects.

Awesome NestJS Boilerplate

There are some performance-related issues:

  1. Redundant queries to DB in jwt.strategy which will execute on each request (code).

         const user = await this.userService.findOne({
           // FIXME: issue with type casts
           id: args.userId as never,
           role: args.role,
         });
    

    This can reduce the performance of your application.

  2. Tables are not optimised: indexes are not created (code).

       @ManyToOne(() => UserEntity, (userEntity) => userEntity.posts, {
         onDelete: 'CASCADE',
         onUpdate: 'CASCADE',
       })
       @JoinColumn({ name: 'user_id' })
       user: UserEntity;
    

    On a large dataset, the application will work slowly, for example for “get posts by user”.

There are imperfections with file upload:

  • There is no validation for file size and mime type.

  • File uploading follows some bad practices: for each endpoint, we need to write weird logic for handling files.

Auth flow is not complete. Email confirmation and Forgot password flows are missing.

NestJS Prisma Starter

Some performance issues:

  1. The issue is similar to Awesome NestJS Boilerplate: redundant queries to DB (code).

       validateUser(userId: string): Promise<User> {
         return this.prisma.user.findUnique({ where: { id: userId } });
       }
    

    This can reduce the performance of your application.

  2. Some tables are not optimised: indexes are not created (code) and on a large dataset the application will work slowly.

Auth flow is not complete. Email confirmation and Forgot password flows are missing.

And there is no file uploading feature, which is usually necessary.

Squareboat NestJS Boilerplate

There is only a NestJS + database setup, with its own solutions which will be hard to support in the future.

Nest Hackathon Starter

This boilerplate has a well-designed schema, with optimisation, but still, there is a problem with performance: jwt.strategy makes redundant queries to DB which will execute on each request (code).

    const user = await this.authService.validateUser(payload);

Also, the mailing system has some anti-patterns.

  1. Own template solution (code).

         const mail = confirmMail
           .replace(new RegExp('--PersonName--', 'g'), name)
           // ... a few more lines here
           .replace(new RegExp('--ButtonLink--', 'g'), buttonLink)
           .replace(
             new RegExp('--TermsOfServiceLink--', 'g'),
             config.project.termsOfServiceUrl,
           );
    

    This will be hard to support in the future.

  2. Part of the templates is stored in the service file (code).

           .map(
             (social) =>
               `<a href="${social[1]}" style="box-sizing:border-box;color:${config.project.color};font-weight:400;text-decoration:none;font-size:12px;padding:0 5px" target="_blank">${social[0]}</a>`,
           )
    

Also, I would notice a badly designed service config. Configs are stored in JS object (code), without env configuration. This can cause problems with security.

Brocoders NestJS Boilerplate

I wouldn’t say too much about this Boilerplate as I wrote most of it and it would be difficult to criticise it :-)

But I’d like to note that I mostly followed official documentation of REST API and NestJS techniques. I tried to focus on performance and long support along with e2e tests.

It includes all necessary features for auth (sign in, sign up, social sign up, confirm email, forgot password and roles) and file uploading (this allows one endpoint for file uploading and then attaching it to any other entity). I decided to have it from the box because all the projects we started required these features.

Conclusion

Actually from the code review standpoint, all of the selected solutions are good. Nothing critical, any of such issues can be easily resolved in your own implementation. However, it makes sense to select the starter kit knowing all the differences between solutions and making your choice consciously. Also now, hopefully, you know a bit more about some good and bad practices, so can better design your application.

Thanks to @Vlad Shchepotin for helping with this article.