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
$ 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
## 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:
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
As a development dependencies, we got:
npm install --save-dev typescript @types/node @nestjs/cli @nestjs/schematics
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 ."
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"
}
}
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
## 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
## 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
## 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 🎊
For development:
## For development
npm run start:dev
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 .
Everything in a bash script: https://github.com/micalevisk/create-nest/blob/main/create-nestjs-from-scratch.sh
Top comments (2)
now you can just run:
npm init nest -- <dir>
to bootstrap that apphere's a full example on this + not using
@nestjs/cli
at all: gitlab.com/micalevisk/really-bare-...