The Best NestJS Boilerplate to Start Your New Project

Written by rodik | Published 2023/04/13
Tech Story Tags: nestjs | nodejs | javascript | nodejs-developer | nodejs-tutorial | nodejs-apps | node.js-development | javascript-development

TLDRThere are 5 boilerplates reviewed it this article (out of 30+ presented in the Awesome NestJS list). In general all of them are decent to take a look at, but in order to choose what fits you best you can use a table of features provided in this article. Also you can learn about some bad and good practices based on the code review of NestJS boilerplates: the most common issues are performance (unnecessary queries) or database indexes.via the TL;DR App

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 basically 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 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 we 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:

Stars

Contributors

Last Commit Date

Open Issues

Approach

NestJS REST API Boilerplate

860

8 contributors, most of code written by 1 developer, supported by Brocoders company

26-03-2023

3

REST API

Awesome NestJS Boilerplate

1.6K

15 contributors, most of code written by 1 developer

18-03-2023

9

REST API

NestJS Prisma Starter

1.7K

22 contributors, most of code written by 1 developer

23-01-2023

4

GraphQL

Squareboat NestJS Boilerplate

469

10 contributors, most of code written by 1 developer

01-03-2023

4

REST API

Nest Hackathon Starter

279

6 contributors, most of code written by 1 developer

24-01-2023

1

REST API

Now we are going to compare them by features.

Features

NestJS REST API Boilerplate

Awesome NestJS Boilerplate

NestJS Prisma Starter

Squareboat NestJS Boilerplate

Nest Hackathon Starter

Documentation

+

Legacy

+

+

-

Sign in / Sign up

+

+

+

-

+

Social sign in

+

-

-

-

-

Roles

+

+

+

-

-

Confirm email

+

-

-

-

+

Forgot password

+

-

-

-

-

Config Service

+

+

+

-

-

Mailing

+

-

-

+

+

Translations

+

+

-

+

-

Database

+ (PostgreSQL, TypeORM)

+ (PostgreSQL, TypeORM)

+ (PostgreSQL, Prisma)

+ (Knex)

+ (PostgreSQL, Prisma)

Migrations

+

+

+

+

+

Seeding

+

-

+

+

-

File upload

Local, AWS S3, Can extend

AWS S3, Can not extend

-

-

-

Tests

+

+

+

+

+

CI

E2E tests, linter

Linter

Unit tests

-

-

Swagger

+

+

+

-

+

Docker

+

+

+

-

-

Auto updating dependencies

+

-

-

-

+ (But without tests. It can break build)

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 is 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,
        });
    

  2. This can reduce performance of your application.

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

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

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

There are imperfections with file upload:

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

  2. 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 optimized: 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 that 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 well designed schema, with optimization, 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,
          );
    

  2. This will be hard to support in the future.

  3. A part of templates are 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 criticize 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 attach 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 you can better design your application.

Thanks to @Vlad Shchepotin for helping with this article.


Written by rodik | Tech geek with 10+y exp | Startup Wise Guys alumni | Co-founder of CASERS and Brocoders
Published by HackerNoon on 2023/04/13