Trying out NestJS part 1: Setting up dev environment for your React / NestJS applications that rocks


In the context of my current job, I wanted to evaluate the various existing backend frameworks based on NodeJS. Why is that? The only Node.js backend framework I had ever used so far was express, which is an awesome light-weight framework, but that doesn't have any opinion whatsover on how you should structure your app.

During my investigation, I came across NestJS several times. The most appealing thing to me was its thorough documentation and its large ecosystem. I was especially interested in the OpenAPI integration, which I knew could greatly improve the frontend development experience when coupled with a code generator. In the end, I decided to create a small POC to see whether it would be a fit.

Specifications of the project

Functional requirements

The POC is going to be a minimal, hideous "TODO list" app (styling is not in the scope of this endeavor). In this POC, I'll be able to:

  • Add tasks,
  • Remove tasks,
  • List all tasks

Technical requirements

  • Use Typescript everywhere.
  • NestJS for the backend.
  • React for the frontend.
  • Tasks are saved in a Postgres DB.
  • Redis is used for caching responses.
  • API endpoints are documented using OpenAPI.
  • API endpoints' parameters are validated in the backend.
  • Frontend code related to the API endpoints is auto-generated.
  • The development environment is set up in docker.
  • Monorepo containing both the backend and the frontend.

Building the project

The source code for this part of the project is available here:

Setting up Docker dev environment

Since I took Docker and Kubernetes: The Complete Guide and Microservices with Node JS and React courses, I've been a huge fan of setting up my dev environment inside docker instances instead of setting it up directly on my machine. I love the fact that I can have everything up and running with a single command, without having to worry about dependency conflicts (is my current version of NPM compatible with that project?, etc.).

A few commands to execute

  • Install the Nest CLI: npm i -g @nestjs/cli (you might need to prefix it with sudo)
  • Create an empty folder: mkdir todo-list-app
  • Go inside the folder: cd todo-list-app
  • Init npm package: npm init -y
  • Init git, if you want to save your work: git init
  • Create frontend folder: mkdir -p packages/react-app
  • Create backend folder: mkdir -p packages/nestjs
  • Create the React app: npx create-react-app packages/react-app --template typescript
  • Create the NestJS app: nest new packages/nestjs
  • Delete the .git folder automatically created by NestJS: rm -rf packages/nestjs/.git
  • Create frontend env variables file: touch packages/react-app/
  • Create backend env variables file: touch packages/nestjs/
  • Create frontend Dockerfile for dev environment: touch packages/react-app/
  • Create backend Dockerfile for dev environment: touch packages/nestjs/
  • Create docker-compose file for dev environment: touch docker-compose.yml
  • Create frontend .dockerignore file: touch packages/react-app/.dockerignore
  • Create backend .dockerignore file: touch packages/nestjs/.dockerignore

A few files to fill / change

FROM node:alpine WORKDIR /app COPY package.json . RUN npm install --legacy-peer-deps COPY . . CMD ["npm", "run", "start"]

--legacy-peer-deps is just a temporary fix for

FROM node:alpine WORKDIR /app RUN npm install -g @nestjs/cli COPY package.json . RUN npm install COPY . . CMD ["npm", "run", "start:dev"]

Nothing crazy here, but we just make sure we install the NestJS CLI globally before doing anything else.


CHOKIDAR_USEPOLLING is required when developing inside a docker container and using create-react-app ( The other variables are defined so that we can communicate with the NestJS API.


We define the port on which NestJS will run as well as the Postgres and Redis configs.


We don't want the local node_modules folder to be copied over the instance.

version: "3.5" services: nestjs: build: context: ./packages/nestjs dockerfile: env_file: - ./packages/nestjs/ ports: - 3001:3001 volumes: - ./packages/nestjs/:/app - /app/node_modules react_app: build: context: ./packages/react-app dockerfile: env_file: - ./packages/react-app/ ports: - 3000:3000 volumes: - ./packages/react-app/:/app - /app/node_modules postgres: image: postgres:13.1 environment: POSTGRES_PASSWORD: example ports: - 5432:5432 redis: image: redis:6.2-rc1 environment: REDIS_PASSWORD: password redis_commander: image: rediscommander/redis-commander:latest restart: always environment: - REDIS_HOSTS=local:redis:6379 ports: - 8081:8081 depends_on: - redis
  • nestjs is our backend.
  • react_app is our frontend.
  • postgres is going to be used to store the tasks.
  • redis is going to be used by NestJS to cache responses.
  • redis_commander is just a tool that allows us to examine the Redis DB quickly.
  • volumes under reactapp and nestjs is key to get auto-reload whenever you modify files inside your editor. The only annoying thing with this setup is that you'll need to rebuild your docker images whenever you add a new dependency inside your nodemodules (see for fixes).
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(process.env.NEST_PORT); } bootstrap();

Modify the port the app is listening to using the process.env.NEST_POST environment variable (defined in packages/nestjs/

Test current setup

You should now be able to start your dev environment typing docker-compose up in the root directory.

You can then go to the following addresses:

  • localhost:3000 --> React app.
  • localhost:3001 --> NestJS app.
  • localhost:8081 --> Redis Commander (which should be connected to your Redis instance).

Final words

With the current state, I've a working dev environment inside dev containers. All I have to do to get started is docker-compose up (sometimes, I have to do a docker-compose up --build, depending on whether or not new npm packages have been installed). Whenever I update any .ts files in my code editor, the apps are reloaded accordingly, making it a very pleasant dev experience for the task at hand: asserting whether or not NestJS is going to be a good fit for me by developing a POC.

Part 2 is available here.

Arnaud Cortisse © 2021