npm & Packages
npm (Node Package Manager) gives you access to over 2 million packages. Need to send emails, parse dates, validate forms, or build APIs? There's a package for that.
Initializing a Project
Every Node.js project starts with package.json. Create it:
mkdir my-project
cd my-project
npm init -y
The -y flag accepts all defaults. You'll get:
{
"name": "my-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Installing Packages
Let's install lodash, a popular utility library:
npm install lodash
What happened:
lodashwas added tonode_modules/folderpackage.jsonnow has a "dependencies" sectionpackage-lock.jsonwas created (locks exact versions)
{
"dependencies": {
"lodash": "^4.17.21"
}
}
Using an Installed Package
// app.js
const _ = require('lodash');
const numbers = [1, 2, 3, 4, 5];
console.log(_.sum(numbers)); // 15
console.log(_.reverse([...numbers])); // [5, 4, 3, 2, 1]
console.log(_.chunk(numbers, 2)); // [[1, 2], [3, 4], [5]]
const users = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 35 }
];
console.log(_.maxBy(users, 'age')); // { name: 'Charlie', age: 35 }
Run it:
node app.js
Output:
15
[ 5, 4, 3, 2, 1 ]
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
{ name: 'Charlie', age: 35 }
dependencies vs devDependencies
# Regular dependency (needed to run your app)
npm install express
# Dev dependency (only needed during development)
npm install -D nodemon
{
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
devDependencies are for:
- Testing (jest, mocha)
- Linting (eslint)
- Build tools (webpack, typescript)
- Development utilities (nodemon)
Common npm Commands
# Install all dependencies from package.json
npm install
# Install a specific package
npm install axios
# Install as dev dependency
npm install -D jest
# Install globally (available everywhere)
npm install -g nodemon
# Uninstall a package
npm uninstall lodash
# Update packages
npm update
# See outdated packages
npm outdated
# Run a script from package.json
npm run start
npm test
npm Scripts
Add custom commands to package.json:
{
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js",
"test": "jest",
"lint": "eslint ."
}
}
Run them:
npm start # Runs: node app.js
npm run dev # Runs: nodemon app.js
npm test # Runs: jest (test is special, no 'run' needed)
npm run lint # Runs: eslint .
The node_modules Folder
When you npm install, packages go into node_modules/. It gets big:
du -sh node_modules
# 50M node_modules (can easily be 200MB+ in real projects)
Golden rule: Never commit node_modules to git.
Create .gitignore:
node_modules/
Anyone who clones your project just runs npm install to recreate it.
package-lock.json
This file locks exact versions:
{
"packages": {
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
}
}
}
Commit this file. It ensures everyone gets the exact same versions.
Finding Packages
- npmjs.com - Search the registry
- GitHub - Most packages are open source
- bundlephobia.com - Check package size before installing
| Need | Package |
|---|---|
| HTTP requests | axios, node-fetch |
| Dates | dayjs, date-fns |
| Validation | joi, yup, zod |
| Environment vars | dotenv |
| Unique IDs | uuid, nanoid |
| Web framework | express, fastify |
Try It Yourself
Create a project that uses multiple packages:
mkdir date-project
cd date-project
npm init -y
npm install dayjs chalk
app.js:
const dayjs = require('dayjs');
const chalk = require('chalk');
const now = dayjs();
console.log(chalk.blue('Current time:'), now.format('HH:mm:ss'));
console.log(chalk.green('Today:'), now.format('MMMM D, YYYY'));
console.log(chalk.yellow('This week:'), 'Week', now.week());
console.log(chalk.red('Days until 2025:'), dayjs('2025-01-01').diff(now, 'day'), 'days');
Run it:
node app.js
Output (with colors!):
Current time: 14:32:15
Today: January 22, 2026
This week: Week 4
Days until 2025: -386 days
Key Takeaways
- npm init creates package.json
- npm install pkg adds a dependency
- npm install -D pkg adds a dev dependency
- node_modules/ is auto-generated, never commit it
- package-lock.json locks versions, do commit it
- npm scripts let you define custom commands
Next, let's understand the magic behind Node.js - the Event Loop!