Install & Use npm Packages

18 min read·Jan 1, 2025

In npm, packages can be downloaded and installed in two different ways: locally and globally.

A local package is a package installed within the top-level directory of a project and cannot be accessed by other projects on your machine.

It allows each project to manage their own packages independently, without interfering with others.

A global package, on the other hand, is a package installed within the global npm installation directory and can be accessed by any project on your machine.

It may also include command-line tools that can be run from any directory.

Initialize a project

Before being able to install packages locally, you will have to initialize the project you want to install the packages into, which essentially means creating a package.json file.

The package.json file

The package.json file is a special type of file called a dependency declaration manifest.

It includes the list of packages your project depends on (its dependencies) and their versions, as well as additional information about the project itself, such as its name, description, author, repository URL, and so on.

When installing a local package, npm automatically updates the package.json file to include it in the list of dependencies, so that they can be easily reinstalled in the future; since the dependencies of a project are not supposed to be uploaded on a version control system such as Git.

Create the package.json file

To initializing a new or existing project, you can:

  1. Enter your project's directory

    $ cd ~/projects/api
    
  2. Use the npm init command, which will prompt you with a series of questions that will help you describe your project.

    $ npm init
    package name: (myproject)
    version: (1.0.0)
    description:
    entry point: (index.js)
    test command:
    git repository:
    keywords:
    author:
    license: (ISC)
    

    To each question, you can either directly press the ENTER key to keep the default value in parenthesis or left blank, or you can type in your own value and press the ENTER key.

  3. To the last question "Is this OK? (yes)", press ENTER one last time to complete the process and create the file.

  4. Review the package.json file generated in the top-level directory of your project containing all the information you've just entered.

    $ cat package.json
    {
      "name": "myproject",
      "version": "1.0.0",
      "description": "A demo project",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "Razvan Ludosanu",
      "license": "ISC"
    }
    

Install packages from the registry

As mentioned in the introduction, npm packages can be installed in two different ways: locally and globally.

Install a local package

To install a package within a specific project, you can navigate to your project's directory and use the npm install command:

$ npm install package ...

Where package ... is a list of package names.

When executed, npm will automatically:

  1. Download the packages and their dependencies from the official npm registry into the node_modules directory located in the top-level directory of the project.
  2. Create the lock file of the dependency declaration manifest named package-lock.json, if it doesn't exist.

The node_modules directory

The node_modules directory contains all the locally downloaded packages of your project.

It is the directory Node.js will look into when importing a module within the code of your application using either the require function or the import directive.

Note: This directory should never be uploaded to a version control system, such as Git.

The package-lock.json file

The package-lock.json file provides a detailed record of the exact dependency tree of your project.

Its role is to ensure consistency across deployment environments and prevent compatibility issues between different versions of the same package.

It is automatically updated by npm whenever a package is installed, updated, or removed.

Note: This file should always be uploaded to a version control system, so that every developers collaborating on the same project can work locally with the same configuration.

Example

Let's consider this initialized directory named app:

~/projects/app$ ls
package.json

To install the uuid package used to generate RFC4122 universally unique identifiers, you can use this command:

~/projects/app$ npm install uuid

added 1 package, and audited 2 packages in 819ms

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

When executed, it will:

  1. Add the uuid package and its installed version under the dependencies property of the package.json file:

    $ cat package.json
    {
      "name": "app",
      "version": "1.0.0",
      "description": "A demo app",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "Razvan Ludosanu",
      "license": "MIT",
      "dependencies": {
        "uuid": "^11.0.3"
      }
    }
    
  2. Create a new file named package-lock.json containing additional information about the installed package:

    {
      "name": "app",
      "version": "1.0.0",
      "lockfileVersion": 3,
      "requires": true,
      "packages": {
        "": {
          "name": "app",
          "version": "1.0.0",
          "license": "MIT",
          "dependencies": {
            "uuid": "^11.0.3"
          }
        },
        "node_modules/uuid": {
          "version": "11.0.3",
          "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz",
          "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==",
          "funding": [
            "https://github.com/sponsors/broofa",
            "https://github.com/sponsors/ctavan"
          ],
          "bin": {
            "uuid": "dist/esm/bin/uuid"
          }
        }
      }
    }
    
  3. Create a new directory named node_modules that contains the files of the uuid package:

    ~/projects/app$ ls node_modules/uuid/
    CHANGELOG.md	CONTRIBUTING.md	LICENSE.md	README.md	dist		package.json
    

Once installed, you can import and use this package within your project's files, just like any other package:

// File: index.js

const uuid = require('uuid');

console.log(uuid.v4());

Note: When running the script, Node.js will automatically look for the specified package into the node_modules directory of your project.

Install a global package

To install a global package, you can use the npm install command with the -g flag (short for global):

$ npm install -g package ...

Once installed, you can directly import it within the code of any of your projects using either the require function or the import directive.

Notes:

  • Installing a global package will not update the package.json and package-lock.json files of your projects.

  • Global packages are installed in a different directory, whose path can be determined using the npm root -g command.

Good practice:

  • Applications and scripts should never rely on the implicit existence of globally installed packages on the system.

  • The installation and use of global packages should be limited to packages intended for command-line use, such as tools or process managers.

Install a specific package version

By default, npm will install the latest available version of the specified package.

To install a specific version instead, you can use the npm install command with this syntax:

$ npm install package@version|tag

Where:

  • package is the name of the package you want to install (e.g. express).
  • version is the semver version of the package (e.g. 4.18.2).
  • tag is the version tag of the package (e.g. next).

Example

For example, this command will install the express package at version 4.18.2:

$ npm install express@4.18.2

And this other command will install the uuid package using the beta tag, which corresponds to version 9.0.0-beta.0:

$ npm install uuid@beta

dependencies, devDependencies, and peerDependencies

In npm, packages referred to as project dependencies can be of three types: production, development, and peer dependencies.

Production dependencies

Production dependencies, or simply dependencies, are packages that your project requires in order to run.

They provide functionality that your code relies on at runtime, such as a web server framework or a database driver.

They are specified in the dependencies property of the package.json file:

{
  "dependencies": {
    "express": "^4.18.2"
  }
}

Note: By default, all the packages installed using the npm install command will be listed under the dependencies object.

Development dependencies

Development dependencies are packages that are only required during the development of your application.

They provide functionality that is useful for development and testing, such as a testing framework, a code linter, or a build tool.

They are installed using the --save-dev flag:

$ npm install --save-dev package ...

They are specified in the devDependencies property of the package.json file:

{
  "devDependencies": {
    "jest": "^29.6.4"
  }
}

Peer dependencies

Peer dependencies are packages that your project expects to be installed in the user's environment.

These packages are not installed automatically as the user is expected to install them manually.

They are specified in the peerDependencies property of the package.json file:

{
  "peerDependencies": {
    "react": "^17.0.0"
  }
}

Note: Peer dependencies names and versions must be manually specified in the peerDependencies property of the package.json file, as there is currently no npm command available to do it automatically.

Install a project's dependencies

To automatically download all the dependencies listed under the dependencies and devDependencies properties of the package.json file, you can use the npm install command without arguments within the top-level directory of the project:

$ npm install

Note: This is mostly useful when downloading a fresh copy of a project that doesn't include the node_modules directory.

Install production packages only

When deployed to production or staging environments, applications usually only require their production dependencies.

To avoid unnecessarily installing the development dependencies, and therefore reducing the deployment time, the CPU load, and the overall build size of your application, you can use npm install command with the --production flag, which will tell npm to only install the packages listed under the dependencies property of the package.json file:

$ npm install --production

Alternatively, you can locally set the NODE_ENV environment variable to production:

$ NODE_ENV=production npm install

Install development packages only

To only install the development dependencies, you can use the npm install command with the -only=dev flag, which will tell npm to only install the packages listed under the devDependencies property of the package.json file:

$ npm install --only=dev

Alternatively, you can locally set the NODE_ENV environment variable to development:

$ NODE_ENV=development npm install

Reinstall a project's dependencies

It may sometimes happen that broken dependencies prevent your application from running properly.

To fix this issue, you can first remove the node_modules directory:

$ rm -r node_modules

And re-install all the dependencies using the npm install command:

$ npm install

Summary

Here's a summary of what you've learned in this lesson:

  • Packages can be installed locally and globally.
  • The package.json file contains information about the project and its dependencies.
  • The package-lock.json file contains the exact dependency tree of the project.
  • The node_modules directory contains the source code of the dependencies.
  • The npm init command is used to generate the package.json file.
  • There are three types of dependencies: dependencies, devDependencies, and peerDependencies.
  • The npm install <package> command is used to download and install specific dependencies.
  • The npm install command is used to download and install all the dependencies defined in the package.json file.
  • The -g flag is used to install packages globally.
  • The --save-dev flag is used to install packages as devDependencies.
  • The --production flag is used to install production dependencies only.
  • The --only=dev flag is used to install development dependencies only.

Enjoying the courses?

I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:

Support BackendBrewery
Install & Use Packages in npm | Backend Brewery