DEV Community

Micael Levi L. C.
Micael Levi L. C.

Posted on • Edited on

5 steps to create a bare minimum NestJS app from scratch!

Let's say you want to create a new NestJS standard application from scratch but taking the full control of your dependencies, scripts and source code. Thus, you don't want to use the usual npx @nestjs/cli new command (which basically bootstraps the typescript starter project) since you wish a bare minimum app.

The goal of this guide is to show you what you really need in order to start a standard (ExpressJS-based HTTP server) NestJS app.

Tools used here

  • node.js v18 -- runtime
  • npm v9 -- package manager
  • npx v9 -- utility to execute NPM packages binaries
  • bash shell -- Terminal stuff. We'll use here documents UNIX feature to write files via terminal but you can replace this with your IDE such as VS Code.

You can use newer versions of them, of course.

Final file structure

As a result we would have this:

.
├── nest-cli.json
├── package.json
├── package-lock.json
├── src
│   ├── app.module.ts
│   └── main.ts
├── tsconfig.build.json
└── tsconfig.json

1 directory, 7 files
Enter fullscreen mode Exit fullscreen mode
$ npm ls --depth=0
my-nestjs-app@1.0.0 /tmp/my-nestjs-app
├── @nestjs/cli@9.1.5
├── @nestjs/common@9.2.1
├── @nestjs/core@9.2.1
├── @nestjs/platform-express@9.2.1
├── @types/node@18.11.13
├── reflect-metadata@0.1.13
└── typescript@4.9.4
Enter fullscreen mode Exit fullscreen mode

With 3 development dependencies and 4 production dependencies. And only 3 NPM scripts.

1. NPM project setup

## Create the new directory that will holds our app's code
mkdir my-nestjs-app
## Enter on it
cd $_
## Start the NPM project
npm init --yes
Enter fullscreen mode Exit fullscreen mode

2. Install all mandatory dependencies

As a hard/production dependencies, we need:

npm install reflect-metadata @nestjs/common @nestjs/core
##          |
##          +--> For TS decorators instrospection
## Since we'll use express as the underlying HTTP lib:
npm install @nestjs/platform-express
Enter fullscreen mode Exit fullscreen mode

As a development dependencies, we got:

npm install --save-dev typescript @types/node @nestjs/cli @nestjs/schematics
Enter fullscreen mode Exit fullscreen mode

You can learn more about NPM dependencies here.

3. Add useful npm-scripts to package.json

To help on bulding and running our app, we can add few useful npm-scripts:

## Remove the 'test' npm-script that was generated by NPM before
npm pkg delete scripts.test
## Change the 'main' entry to the right entry file that we'll have afte building the project
npm pkg set main="dist/src/main"

## Define the 'build' script,
## that will be used to compile our TypeScript code into JavaScript
npm pkg set scripts.build="nest build"

## Define the 'start:dev' script,
## that will be used to build & run the app with the watch mode
npm pkg set scripts.start:dev="nest start --watch"

## Define the 'start:prod' script,
## that will be used to run the compiled code 
npm pkg set scripts.start:prod="node ."
Enter fullscreen mode Exit fullscreen mode

The package.json should looks like this:

{
  "name": "my-nestjs-app",
  "version": "1.0.0",
  "description": "",
  "main": "dist/src/main",
  "scripts": {
    "build": "nest build",
    "start:dev": "nest start --watch",
    "start:prod": "node ."
  },
  "dependencies": {
    "@nestjs/common": "^9.2.1",
    "@nestjs/core": "^9.2.1",
    "@nestjs/platform-express": "^9.2.1",
    "reflect-metadata": "^0.1.13"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.1.5",
    "@nestjs/schematics": "^9.0.0",
    "@types/node": "^18.11.13",
    "typescript": "^4.9.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Create all required files

  • We'll create a src directory with a NestJS module,
  • a tsconfig.json file in the root,
  • a tsconfig.build.json file in the root to use when compiling the TypeScript project for production,
  • a nest-cli.json file in the root, to configure NestJS's CLI.

If you're not familiar with the configuration options we'll use in those TypeScript configuration files (tsconfig ...), check out their docs: https://www.typescriptlang.org/tsconfig

## Create the 'src' directory to store source files
mkdir src
Enter fullscreen mode Exit fullscreen mode
## Create the TypeScript configuration file with good defaults
cat <<EOF > tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2021",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./",
    "baseUrl": "./",
    "skipLibCheck": true,
    "incremental": true
  }
}
EOF

## Create the TypeScript config file
## that will be used when building the project with NestJS's CLI
cat <<EOF > tsconfig.build.json
{
  "extends": "./tsconfig.json",
  "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
EOF
Enter fullscreen mode Exit fullscreen mode
## Create the NestJS CLI config file
## Do note that we don't want to generate spec files while using the 'generate' command
## since we are not using Jest in this tutorial
## Also, Jest isn't mandatory.
## You could use any other testing framework that works with TS decorators
cat <<EOF > nest-cli.json
{
  "\$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "monorepo": false,
  "sourceRoot": "src",
  "entryFile": "main",
  "language": "ts",
  "generateOptions": {
    "spec": false
  },
  "compilerOptions": {
    "tsConfigPath": "./tsconfig.build.json",
    "webpack": false,
    "deleteOutDir": true,
    "assets": [],
    "watchAssets": false,
    "plugins": []
  }
}
EOF
Enter fullscreen mode Exit fullscreen mode
## Create a minimal application root module
npx nest generate module app --flat

## Create a minimal application entrypoint under src/main.ts file
cat <<EOF > src/main.ts
import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  await app.listen(process.env.PORT || 3000);
}
bootstrap();
EOF
Enter fullscreen mode Exit fullscreen mode

5. Run the app 🎊

For development:

## For development
npm run start:dev
Enter fullscreen mode Exit fullscreen mode

For production:

## Setup for production
npm run build
## Delete the 'node_modules' directory
rm -rf node_modules
## Install production-only dependencies without changing the lock file
npm ci --omit=dev
## Start the app using it's 'main' entry
node .
Enter fullscreen mode Exit fullscreen mode

Everything in a bash script: https://github.com/micalevisk/create-nest/blob/main/create-nestjs-from-scratch.sh

Top comments (2)

Collapse
 
micalevisk profile image
Micael Levi L. C.

now you can just run: npm init nest -- <dir> to bootstrap that app

Collapse
 
micalevisk profile image
Micael Levi L. C.

here's a full example on this + not using @nestjs/cli at all: gitlab.com/micalevisk/really-bare-...