DEV Community

Cover image for Trying out NestJS part 1: Setting up a dev environment for your React / NestJS applications that rocks
Arnaud Cortisse
Arnaud Cortisse

Posted on • Edited on

7 2

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

This article was originally published on my personal blog.

Introduction

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: https://github.com/arnaud-cortisse/trying-out-nestjs-part-1.

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/.env.dev
  • Create backend env variables file: touch packages/nestjs/.env.dev
  • Create frontend Dockerfile for dev environment: touch packages/react-app/Dockerfile.dev
  • Create backend Dockerfile for dev environment: touch packages/nestjs/Dockerfile.dev
  • 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

packages/react-app/Dockerfile.dev
FROM node:alpine
WORKDIR /app

COPY package.json .
RUN npm install --legacy-peer-deps
COPY . .

CMD ["npm", "run", "start"]
Enter fullscreen mode Exit fullscreen mode

--legacy-peer-deps is just a temporary fix for https://github.com/facebook/create-react-app/issues/9515.

packages/nestjs/Dockerfile.dev
FROM node:alpine

WORKDIR /app
RUN npm install -g @nestjs/cli
COPY package.json .
RUN npm install
COPY . .

CMD ["npm", "run", "start:dev"]
Enter fullscreen mode Exit fullscreen mode

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

packages/react-app/.env.dev
REACT_APP_BACKEND_SCHEMA=http
REACT_APP_BACKEND_HOSTNAME=localhost
REACT_APP_BACKEND_PORT=3001
CHOKIDAR_USEPOLLING=true
Enter fullscreen mode Exit fullscreen mode

CHOKIDAR_USEPOLLING is required when developing inside a docker container and using create-react-app (https://github.com/facebook/create-react-app/issues/1049#issuecomment-261731734).
The other variables are defined so that we can communicate with the NestJS API.

packages/nestjs/.env.dev
NEST_PORT=3001
PGHOST=postgres
PGPORT=5432
PGUSER=postgres
PGPASSWORD=example
PGDATABASE=postgres
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=password
REDIS_TTL=10
Enter fullscreen mode Exit fullscreen mode

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

packages/react-app/.dockerignore
node_modules
Enter fullscreen mode Exit fullscreen mode

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

packages/nestjs/.dockerignore
node_modules
Enter fullscreen mode Exit fullscreen mode
docker-compose.yml
version: "3.5"

services:
  nestjs:
    build:
      context: ./packages/nestjs
      dockerfile: Dockerfile.dev
    env_file:
     - ./packages/nestjs/.env.dev
    ports:
      - 3001:3001
    volumes:
      - ./packages/nestjs/:/app
      - /app/node_modules

  react_app:
    build:
      context: ./packages/react-app
      dockerfile: Dockerfile.dev
    env_file:
     - ./packages/react-app/.env.dev
    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
Enter fullscreen mode Exit fullscreen mode
  • 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 react_app 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 node_modules (see https://github.com/BretFisher/node-docker-good-defaults for fixes).
packages/nestjs/src/main.ts
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();

Enter fullscreen mode Exit fullscreen mode

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

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.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post