5 steps to create a bare minimum NestJS app from scratch!
Tags: nestjs, node, tutorial
Published: 2022-12-11 19:27:38

> for nestjs v8, v9 and v10

Let's say you want to create a new [NestJS](https://nestjs.com) 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](https://github.com/nestjs/typescript-starter) project) since you wish a bare minimum app.

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

#### Tools used here

- node.js v16 -- runtime
- npm v9 -- package manager
- npx v9 -- utility to execute NPM packages binaries
- bash shell -- Terminal stuff. We'll use [here documents](https://en.wikipedia.org/wiki/Here_document#Unix_shells) 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:

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

1 directory, 7 files
```

```bash
$ 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
```

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

### 1. NPM project setup

```bash
## 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
```

### 2. Install all mandatory dependencies

As a hard/production dependencies, we need:

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

As a development dependencies, we got:

```bash
npm i -D typescript @types/node @nestjs/cli
```

You can learn more about NPM dependencies [here](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file).

### 3. Add useful npm-scripts to package.json

To help on bulding and running our app, we can add few useful [npm-scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts):

```bash
## 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 ."
```

The `package.json` should looks like this:

```json
{
  "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",
    "@types/node": "^18.11.13",
    "typescript": "^4.9.4"
  }
}
```

### 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

```bash
## Create the 'src' directory to store source files
mkdir src
```

```bash
## 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
```

```bash
## 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
```

```bash
## 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
```

## 5. Run the app 🎊

```bash
## For development
npm run start:dev

## Setup for production
npm run build
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 .
```

---


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