Once Node.js is installed, the fastest way to understand it is to build something with it. This guide walks through the practical steps of starting a project, managing packages, and running a working web server from scratch.
Step 1: Initialize a Project
Every Node.js project starts with a package.json file. This file stores metadata about your project — its name, version, description, entry point, and dependencies.
To create it automatically, run:
npm init -y
The -y flag skips the interactive prompt and accepts all defaults. The generated package.json looks like this:
{
"name": "my-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
You can edit this file manually at any time to update the project name, description, or scripts.
Step 2: Install Packages
Node.js projects rely on npm packages — reusable libraries published to the npm registry. You install them into a node_modules directory inside your project.
Installing a Production Dependency
To install Express.js, a widely used web framework:
npm install express
This command:
- Downloads Express and its dependencies into
node_modules/ - Adds Express to the
dependenciessection ofpackage.json - Creates or updates
package-lock.jsonwhich locks exact versions
Installing a Development Dependency
Some packages are only needed during development and should not be included in the production bundle:
npm install --save-dev nodemon
This adds the package under devDependencies in package.json.
Understanding Dependency Types
| Command | Section in package.json | Purpose |
|---|---|---|
npm install <pkg> | dependencies | Required for the app to run in production |
npm install --save-dev <pkg> | devDependencies | Only needed during development |
Common Production Packages
| Package | Purpose |
|---|---|
| express | Web framework for building servers and APIs |
| dotenv | Load environment variables from .env files |
| mongoose | ODM for working with MongoDB |
| cors | Enable cross-origin resource sharing |
| axios | HTTP client for making API requests |
Common Development Packages
| Package | Purpose |
|---|---|
| nodemon | Auto-restart server when files change |
| eslint | JavaScript linter for code quality |
| jest | Testing framework |
| webpack | Module bundler for frontend assets |
Project Structure After Initialization
my-app/
├── node_modules/ # All installed packages (never commit this)
├── index.js # Your application entry point
├── package.json # Project metadata and dependencies
└── package-lock.json # Locked dependency tree
The node_modules folder should always be added to .gitignore since it can be regenerated from package.json using npm install.
Step 3: Create and Run Your First App
Create the entry point file:
touch index.js
Add the following code to index.js:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello, World!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Run the application:
node index.js
Open your browser and navigate to http://localhost:3000 — you should see Hello, World!
Understanding the Code
const express = require('express');
Import the Express module using CommonJS require.
const app = express();
Create an Express application instance.
app.get('/', (req, res) => { ... });
Define a route. When a GET request arrives at /, execute the callback. req is the request object, res is the response object.
app.listen(PORT, callback);
Start the HTTP server and bind it to the specified port.
Using npm Scripts
Instead of typing node index.js every time, define scripts in package.json:
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
Now you can run:
npm start # Run in production mode
npm run dev # Run in development mode with auto-restart
npm scripts are powerful. They can chain commands, set environment variables, and run complex build pipelines — all from a single short command.
Using nodemon for Development
Restarting the server manually after every change is tedious. nodemon watches your files and automatically restarts the server when changes are detected:
npm install --save-dev nodemon
Update your package.json:
{
"scripts": {
"dev": "nodemon index.js"
}
}
Run the development server:
npm run dev
Now every time you save a file, the server restarts automatically.
Managing Environment Variables
Hardcoding values like port numbers or database URLs in your source code is a bad practice. Use environment variables to keep sensitive configuration outside your code.
Install the dotenv package:
npm install dotenv
Create a .env file in the project root:
PORT=3000
DB_URL=mongodb://localhost:27017/mydb
Load environment variables in your app:
require('dotenv').config();
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello from Node.js!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Add .env to your .gitignore to prevent secrets from being committed to version control.
The package-lock.json File
When you install packages, npm generates a package-lock.json file. This file:
- Records the exact version of every installed package and its sub-dependencies
- Ensures that everyone on the team installs identical dependency trees
- Should always be committed to version control
package.json → Declares what your project needs
package-lock.json → Records exactly what was installed
node_modules/ → Where packages are installed (not committed)
Reinstalling Dependencies
When cloning a project or setting up a new environment, restore all dependencies with:
npm install
npm reads package.json (or package-lock.json) and installs everything automatically.
Final Thoughts
Setting up a Node.js project takes only a few commands. The real power comes from the npm ecosystem — thousands of packages available to solve virtually any problem.
The workflow is straightforward:
npm init -yto create the projectnpm install <package>to add dependencies- Write your code in
index.js - Define npm scripts for convenient execution
- Use
nodemonduring development for automatic restarts
With this foundation, you are ready to build anything from simple APIs to full-featured web applications.