Complete npm Tutorial with Usage Examples

Table of Contents

1. What is npm?

npm (Node Package Manager) is the default package manager for Node.js and the world's largest software registry. It provides two main functionalities:

In essence, npm helps you manage external libraries and tools your JavaScript projects need, making it easy to include complex functionalities without writing everything from scratch.

2. Installing npm

npm is distributed with Node.js. When you install Node.js, npm is installed automatically.

Verify Installation:

Open your terminal or command prompt and run the following commands:

node -v
npm -v

You should see the installed versions of Node.js and npm respectively.

# Example Output:
v20.14.0  # Node.js version
10.7.0   # npm version

3. Initializing a Project (`npm init`)

Before you can use npm to manage dependencies for your project, you need to initialize it. This creates a `package.json` file, which is the heart of any npm project.

Basic Initialization:

Navigate to your project's root directory in the terminal:

mkdir my-npm-project
cd my-npm-project
npm init

npm will then ask you a series of questions (package name, version, description, entry point, test command, git repository, keywords, author, license). You can press Enter to accept the default values for most of these.

# After running npm init and accepting defaults, your package.json might look like this:
{
  "name": "my-npm-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Quick Initialization:

To accept all default values without being prompted, use the `-y` or `--yes` flag:

npm init -y

This is useful for quickly setting up new projects or for scripting.

4. Installing Packages (`npm install`)

This is the most common npm command, used to add external libraries to your project.

A. Installing a Local Package (Project Dependency):

Installs a package into your project's `node_modules` folder and adds it as a dependency in `package.json`.

npm install <package-name>

Example: Installing Express.js (a web framework)

npm install express

This command does two things:

  1. Downloads the `express` package and its own dependencies into a `node_modules` directory in your project's root.
  2. Adds `"express": "^X.Y.Z"` to the `dependencies` section of your `package.json` file. The caret (`^`) denotes a compatible version range.
# package.json after installing express
{
  "name": "my-npm-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2" // This line is added
  }
}

B. Installing a Dev Dependency:

Installs a package needed only during development (e.g., testing frameworks, build tools, linters). These are not deployed with your production code.

npm install <package-name> --save-dev
# Or shorthand:
npm install <package-name> -D

Example: Installing Jest (a testing framework)

npm install jest --save-dev
# package.json after installing jest as a dev dependency
{
  // ...
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": { // This new section is added
    "jest": "^29.5.0"
  }
}

C. Installing Multiple Packages:

You can install several packages at once:

npm install express dotenv mongoose
npm install webpack webpack-cli -D

D. Installing all Project Dependencies:

If you've cloned a project or a `node_modules` folder was deleted, you can install all dependencies listed in `package.json`:

npm install

This command reads `package.json` and `package-lock.json` and installs all necessary packages.

5. Managing Dependencies (package.json & package-lock.json)

These two files are crucial for managing your project's dependencies.

A. `package.json`

This file defines your project's metadata (name, version, description, author, license) and lists its direct dependencies.

# Example package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "description": "A simple Node.js application",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest",
    "dev": "nodemon index.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "dotenv": "^16.0.3"
  },
  "devDependencies": {
    "jest": "^29.5.0",
    "nodemon": "^2.0.22"
  }
}

Dependency Versioning:

B. `package-lock.json`

This file is automatically generated and updated by npm whenever you modify your `node_modules` tree (e.g., `npm install`, `npm update`). It records the exact versions of *all* installed packages and their dependencies (even nested ones), along with their integrity hashes.

Purpose: Ensures that running `npm install` on any machine (or by any developer) will result in the exact same `node_modules` tree, providing consistent builds and preventing "works on my machine" issues.

# Example snippet from package-lock.json (much larger than package.json)
{
  "name": "my-npm-project",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "my-npm-project",
      "version": "1.0.0",
      "devDependencies": {
        "jest": "^29.5.0"
      },
      "dependencies": {
        "express": "^4.18.2"
      }
    },
    "node_modules/accepts": {
      "version": "1.3.8",
      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
      "integrity": "sha512-py/yzLCYmY6F/UtyUzN/P3W+jSykx+Jt0pQ7y1/NfB3+yI+Ew/uF9bFvG8GjA==",
      "dependencies": {
        "mime-types": "~2.1.24",
        "negotiator": "0.6.3"
      }
    },
    // ... many more entries for nested dependencies
  }
}
Important: Always commit both `package.json` and `package-lock.json` to your version control system (e.g., Git).

6. Uninstalling Packages (`npm uninstall`)

Removes a package from your `node_modules` folder and from `package.json`.

Uninstall a Local Package:

npm uninstall <package-name>
# Or shorthand:
npm un <package-name>

Example:

npm uninstall express

Uninstall a Dev Dependency:

npm uninstall <package-name> --save-dev
# Or shorthand:
npm un <package-name> -D

Example:

npm uninstall jest -D

7. Updating Packages (`npm update`)

Updates packages to their latest compatible versions according to the version ranges specified in `package.json`.

Update All Packages:

npm update

This command will check the npm registry for newer versions of all packages (and their dependencies) that satisfy the version ranges in your `package.json` and `package-lock.json`, and then update them in `node_modules` and update `package-lock.json` accordingly.

Update Specific Package:

npm update <package-name>

Major Version Updates (`npm install @latest` or `npm outdated`):

`npm update` will NOT update to a new major version (e.g., from `^1.x.x` to `2.x.x`) because major versions often introduce breaking changes.

To explicitly update to the latest major version (use with caution, check release notes for breaking changes):

npm install <package-name>@latest

To see which packages are outdated (i.e., have newer versions available outside your `package.json` range):

npm outdated

This command shows `Current`, `Wanted` (highest matching `package.json` range), and `Latest` versions.

8. Running Scripts (`npm run`)

The `scripts` section in `package.json` allows you to define custom commands to automate tasks, such as starting your application, running tests, or building your project.

Define a Script:

Add entries to the `scripts` object in `package.json`:

# package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",       // To start your app
    "test": "jest",                 // To run tests
    "dev": "nodemon index.js",      // To run in development mode with auto-restart
    "build": "webpack",             // To build your project for production
    "lint": "eslint .",             // To run a linter
    "hello": "echo Hello, npm!"     // A simple custom script
  },
  "dependencies": { /* ... */ }
}

Run a Script:

npm run <script-name>

Examples:

npm run start
npm run test
npm run dev
npm run build
npm run lint
npm run hello

For `start` and `test` scripts, `npm` provides shorthands:

npm start   # Same as npm run start
npm test    # Same as npm run test
Power of npm scripts: Commands executed by `npm run` automatically have access to executables installed in `node_modules/.bin/`. This means you don't need to specify the full path to `jest`, `webpack`, `eslint`, etc., if they are installed locally as project dependencies.

9. Global Packages (`npm install -g`)

Some tools are command-line utilities that you might want to use across multiple projects or system-wide (e.g., a CLI tool, a code formatter).

Install a Global Package:

npm install -g <package-name>

Example: Installing `create-react-app` CLI tool

npm install -g create-react-app

Now, you can run `create-react-app` from any directory in your terminal.

create-react-app my-new-react-app

List Global Packages:

npm list -g --depth=0 # List top-level global packages

Uninstall a Global Package:

npm uninstall -g <package-name>
Caution with Global Installs: While convenient, global installs can sometimes lead to version conflicts between projects. For development tools, it's often preferred to install them as `devDependencies` and use `npm run` scripts to execute them. Tools like `npx` (covered below) offer a way to run CLI tools without installing them globally.

10. Publishing Packages (`npm publish`)

If you've created your own reusable JavaScript module, you can publish it to the npm registry for others (or yourself) to use.

Steps to Publish:

  1. Create an npm account: If you don't have one, register at npmjs.com.
  2. Log in from CLI:
    npm login

    Follow the prompts for username, password, and email.

  3. Prepare your package.json:
    • Ensure `name` is unique on npm.
    • Set `version` (use Semantic Versioning: MAJOR.MINOR.PATCH).
    • Add a `description`, `keywords`, `author`, `license`.
    • Ensure `main` points to your package's entry file.
    • Include a `repository` field for source control.
  4. Publish:
    npm publish

    This command publishes the package to the public npm registry. If it's a scoped package (e.g., `@yourorg/mypackage`), you might need `--access public` for public scope if it's a new organization.

# Example package.json for publishing
{
  "name": "my-utility-package",
  "version": "1.0.0",
  "description": "A simple utility function for calculations.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": ["utility", "math", "calculator"],
  "author": "Your Name <your.email@example.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/your-username/my-utility-package.git"
  }
}

11. npm audit (Security)

The `npm audit` command checks your project's dependencies for known security vulnerabilities and provides recommendations for remediation.

Run an Audit:

npm audit

This will output a report detailing any vulnerabilities found, their severity, and affected packages.

Fix Vulnerabilities:

npm can often automatically fix many vulnerabilities by updating packages to secure versions.

npm audit fix

For vulnerabilities that cannot be automatically fixed (e.g., requiring a major version upgrade with breaking changes), `npm audit` will provide manual remediation steps.

12. Other Common npm Commands

13. Best Practices with npm

Mastering npm is essential for JavaScript developers.

It's your gateway to a vast ecosystem of reusable code, allowing you to build robust applications more quickly and efficiently. By understanding these commands and best practices, you'll be well-equipped to manage dependencies effectively in any Node.js or frontend project.