Node.js and Express Project Setup
Install Node.js, initialize the application, configure ES Modules, install dependencies, and create a maintainable backend project structure.
Install Node.js and npm
Node.js provides the JavaScript runtime required to execute our backend application.
npm is the package manager used to install Express and other dependencies.
Install an active Node.js LTS release from the official Node.js website.
After installation, open your terminal and verify the installation.
Prerequisites
20+ recommended
npm
Visual Studio Code
Postman or Bruno
Basic JavaScript and HTTP
node --version
npm --versionDisplays the installed Node.js and npm versions.
Node.js executes JavaScript on the server.
npm manages application dependencies.
Use a supported Node.js LTS release.
Create the Express Project
Create a new folder for the REST API application.
Open the terminal and execute the following commands.
The commands create the project directory, navigate into it, and initialize npm.
mkdir nodejs-rest-api
cd nodejs-rest-api
npm init -yCreates the application directory and generates package.json.
Create a separate project directory.
Initialize npm before installing dependencies.
package.json stores application metadata and dependencies.
Configure ES Modules and npm Scripts
We will use ES Modules throughout the tutorial.
Open package.json and configure the module system and scripts.
The type module property allows us to use import and export syntax.
The development script uses Node.js watch mode to restart the server when files change.
{
"name": "nodejs-rest-api",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"start": "node src/server.js",
"dev": "node --watch src/server.js",
"test": "node --test"
}
}Configures the project to use ES Modules and defines application execution scripts.
ES Modules use import and export.
The type module setting enables ES Module interpretation.
npm scripts simplify application execution.
Install Required Dependencies
Install the packages required for the application.
We will use the following dependencies:
- express: Backend web framework.
- mongoose: MongoDB object modeling library.
- dotenv: Loads environment variables.
- cors: Configures cross-origin browser access.
- helmet: Sets security-related HTTP headers.
- express-rate-limit: Protects HTTP endpoints against excessive requests.
- zod: Validates request payloads.
- jsonwebtoken: Signs and verifies JWT tokens.
- bcryptjs: Hashes user passwords.
Install them using npm.
Install Production Dependencies
npm install express mongoose dotenv cors helmet express-rate-limit zod jsonwebtoken bcryptjsInstalls the core framework, database integration, security, validation, and authentication dependencies.
Express handles HTTP requests.
Mongoose provides MongoDB integration.
Zod validates incoming request data.
JWT and bcryptjs provide authentication-related functionality.
Install Development Dependencies
Development dependencies are packages used during development and testing but are not required by the application's runtime implementation.
We will install:
- Jest for automated tests.
- Supertest for HTTP integration testing.
- Nodemon as an alternative development restart utility.
We will use Node.js watch mode in the main development workflow, but Nodemon is included as an alternative.
npm install -D jest supertest nodemonInstalls testing tools and the optional Nodemon development utility.
Development dependencies support local development and testing.
Supertest helps test Express endpoints.
Nodemon is an alternative to Node.js watch mode.
Create a Scalable Project Structure
A maintainable REST API should separate application concerns.
Create the following directory structure:
nodejs-rest-api/
│
├── src/
│ ├── config/
│ │ └── database.js
│ │
│ ├── controllers/
│ │ └── user.controller.js
│ │
│ ├── middleware/
│ │ ├── auth.middleware.js
│ │ ├── error.middleware.js
│ │ └── validate.middleware.js
│ │
│ ├── models/
│ │ └── user.model.js
│ │
│ ├── routes/
│ │ ├── index.js
│ │ ├── user.routes.js
│ │ └── auth.routes.js
│ │
│ ├── services/
│ │ ├── user.service.js
│ │ └── auth.service.js
│ │
│ ├── validators/
│ │ ├── user.validator.js
│ │ └── auth.validator.js
│ │
│ ├── utils/
│ │ └── app-error.js
│ │
│ ├── app.js
│ └── server.js
│
├── tests/
│ └── users.test.js
│
├── .env
├── .env.example
├── .gitignore
└── package.json
Responsibilities:
- config: Database and application configuration.
- controllers: Handle HTTP requests and responses.
- middleware: Authentication, validation, and error handling.
- models: Define MongoDB document structures.
- routes: Define API endpoints.
- services: Implement business logic.
- validators: Define request validation schemas.
- utils: Reusable utility classes and functions.
- tests: Automated test cases.
This structure prevents the application from becoming difficult to maintain as more endpoints are added.
mkdir -p src/config src/controllers src/middleware src/models src/routes src/services src/validators src/utils testsCreates the main backend directories. On Windows PowerShell, use New-Item -ItemType Directory -Force with the required directory paths.
Separate controllers, services, models, and routes.
Keep validation and middleware reusable.
Organize the project before implementing business logic.
Configure Environment Variables
Create a .env file in the project root.
Add the following development configuration:
PORT=3000
NODE_ENV=development
MONGODB_URI=mongodb://127.0.0.1:27017/rest_api_db
JWT_SECRET=replace-with-a-long-random-secret
JWT_EXPIRES_IN=15m
CLIENT_ORIGIN=http://localhost:5173
MONGODB_URI defines the database connection.
JWT_SECRET is used to sign and verify access tokens.
JWT_EXPIRES_IN controls token expiration.
CLIENT_ORIGIN defines the trusted frontend origin.
Create .env.example with the same variable names but safe example values.
Never commit the actual .env file.
Generate a cryptographically secure secret for JWT signing. The example value must be replaced before running authentication functionality.
node_modules/
.env
.env.*
!.env.example
coverage/
logs/
.DS_StorePrevents local environment files, dependencies, test coverage, and logs from being committed.
Environment variables keep configuration outside source code.
Never commit production secrets.
Keep an .env.example file to document required variables.