Modules & NPM

Learn how to work with Node.js modules and manage packages with npm, the world's largest software registry.

Introduction

npm (Node Package Manager) is the world's largest software registry with over 2 million packages. It allows you to install, share, and manage dependencies in your Node.js projects.

What is npm?

  • Package Registry: Hosts millions of reusable code packages
  • CLI Tool: Command-line interface for managing packages
  • Dependency Manager: Automatically handles package dependencies
NPM Basics

Here are the most common npm commands you'll use regularly:

bash
# Initialize a new project
npm init
# Quick initialization with defaults
npm init -y
# Install a package
npm install package-name
npm i package-name # shorthand
# Install as dev dependency
npm install --save-dev package-name
npm i -D package-name # shorthand
# Install globally
npm install -g package-name
# Uninstall a package
npm uninstall package-name
# Update packages
npm update
# List installed packages
npm list
# Check for outdated packages
npm outdated

Package Types

  • Dependencies: Packages your application needs to run in production
    npm install express
  • Dev Dependencies: Packages needed only during development (testing, build tools)
    npm install --save-dev nodemon
  • Global Packages: CLI tools installed system-wide
    npm install -g typescript
package.json

The package.json file is the heart of any Node.js project. It contains metadata about your project and its dependencies.

json
1{
2 "name": "my-app",
3 "version": "1.0.0",
4 "description": "My Node.js application",
5 "main": "index.js",
6 "scripts": {
7 "start": "node index.js",
8 "dev": "nodemon index.js",
9 "test": "jest"
10 },
11 "keywords": ["nodejs", "api"],
12 "author": "Your Name",
13 "license": "MIT",
14 "dependencies": {
15 "express": "^4.18.2",
16 "dotenv": "^16.0.3"
17 },
18 "devDependencies": {
19 "nodemon": "^3.0.1",
20 "jest": "^29.5.0"
21 }
22}

Key Fields

  • name: Package name (required, lowercase, no spaces)
  • version: Package version (required, follows semantic versioning)
  • main: Entry point of your application
  • scripts: Custom commands you can run with npm run
  • dependencies: Packages required for production
  • devDependencies: Packages needed only for development

Running Scripts

bash
# Run a custom script
npm run dev
# Special scripts (no "run" needed)
npm start
npm test
Installing Packages

When you install packages, npm creates a node_modules folder and a package-lock.json file.

Basic Installation

bash
# Install all dependencies from package.json
npm install
# Install specific package
npm install express
# Install specific version
npm install express@4.18.0
# Install latest version
npm install express@latest

The node_modules Folder

This folder contains all installed packages and their dependencies. It can be very large!

Important

Never commit node_modules to version control! Add it to your .gitignore file:

text
# .gitignore
node_modules/
.env

package-lock.json

This file locks down the exact versions of all packages and their dependencies. It ensures consistent installs across different environments.

  • Automatically generated by npm
  • Should be committed to version control
  • Ensures everyone installs the same package versions
Creating Your Own Modules

You can create reusable modules to organize your code better and share functionality across your application.

Example: Logger Module

js
1// utils/logger.js
2function log(message) {
3 const timestamp = new Date().toISOString();
4 console.log(`[${timestamp}] ${message}`);
5}
6
7function error(message) {
8 const timestamp = new Date().toISOString();
9 console.error(`[${timestamp}] ERROR: ${message}`);
10}
11
12function warn(message) {
13 const timestamp = new Date().toISOString();
14 console.warn(`[${timestamp}] WARNING: ${message}`);
15}
16
17module.exports = { log, error, warn };

Using Your Module

js
1// app.js
2const logger = require('./utils/logger');
3
4logger.log('Application started');
5logger.warn('This is a warning');
6logger.error('Something went wrong');
7
8// Output:
9// [2024-01-15T10:30:00.000Z] Application started
10// [2024-01-15T10:30:00.001Z] WARNING: This is a warning
11// [2024-01-15T10:30:00.002Z] ERROR: Something went wrong

Module Best Practices

  • Keep modules focused on a single responsibility
  • Use descriptive file and function names
  • Document your module with comments
  • Export only what's necessary (keep internal functions private)
  • Organize related modules in folders
Semantic Versioning

npm uses semantic versioning (semver) to manage package versions. Understanding version numbers is crucial for managing dependencies.

Version Format: MAJOR.MINOR.PATCH

  • MAJOR (1.0.0): Breaking changes, incompatible API changes
  • MINOR (0.1.0): New features, backward-compatible
  • PATCH (0.0.1): Bug fixes, backward-compatible

Version Ranges

You can specify which versions to accept using special characters:

json
1{
2 "dependencies": {
3 "exact": "4.18.2", // Exactly 4.18.2
4 "caret": "^4.18.2", // >=4.18.2 <5.0.0 (most common)
5 "tilde": "~4.18.2", // >=4.18.2 <4.19.0
6 "greater": ">4.18.2", // Greater than 4.18.2
7 "range": ">=4.18.0 <5.0.0", // Version range
8 "latest": "latest", // Always latest (not recommended)
9 "wildcard": "4.x" // Any 4.x.x version
10 }
11}

Recommended

Use the caret (^) for most dependencies. It allows minor updates and patches while preventing breaking changes: "express": "^4.18.2"

Ready for More?

Now that you understand modules and npm, learn about best practices for writing production-ready Node.js applications!

Built for learning — keep experimenting!