NPM & Package Management
Understanding NPM (Node Package Manager)
NPM is the default package manager for Node.js and the world's largest software registry. It allows developers to share, discover, and use code packages created by the community. NPM is essential for modern Node.js development, providing access to hundreds of thousands of reusable packages.
What is a Package?
A package is a reusable piece of code that can be shared and used across different projects. Packages can range from simple utility functions to complex frameworks like Express.js or React. NPM makes it easy to install, update, and manage these packages in your projects.
npm --version or npm -v in your terminal.
Initializing a Node.js Project
Every Node.js project that uses NPM starts with a package.json file. This file contains metadata about your project and manages its dependencies.
Creating package.json
To create a new package.json file, navigate to your project directory and run:
This command will prompt you with several questions about your project (name, version, description, entry point, etc.). You can press Enter to accept the defaults for any question.
Quick Initialization
To create a package.json file with all default values without answering questions:
This creates a basic package.json file that you can edit later:
Installing Packages
NPM provides several ways to install packages depending on your needs.
Local Installation
To install a package locally in your project:
Or using the shorthand:
This command:
- Downloads the package from the NPM registry
- Installs it in the
node_modulesfolder - Adds it to the
dependenciessection ofpackage.json - Creates or updates
package-lock.jsonto lock dependency versions
Example: Installing Express
After installation, your package.json will include:
Global Installation
Some packages are meant to be installed globally, typically command-line tools:
Examples of globally installed packages:
Dependencies vs DevDependencies
NPM distinguishes between two types of dependencies based on when they're needed.
Dependencies
These are packages required for your application to run in production:
These packages are listed under "dependencies" in package.json.
DevDependencies
These are packages only needed during development (testing tools, build tools, linters):
Or using the shorthand:
These packages are listed under "devDependencies" in package.json:
npm install --production, which skips devDependencies and reduces installation time and size.
Understanding Semantic Versioning
NPM uses semantic versioning (semver) to manage package versions. Version numbers follow the format: MAJOR.MINOR.PATCH
Version Number Format
- MAJOR: Breaking changes (incompatible API changes)
- MINOR: New features (backward-compatible)
- PATCH: Bug fixes (backward-compatible)
Example: 4.18.2 means Major version 4, Minor version 18, Patch version 2
Version Range Symbols
NPM uses special symbols to specify acceptable version ranges:
Managing Installed Packages
Viewing Installed Packages
To see all locally installed packages:
To see only top-level packages (without dependencies):
To view globally installed packages:
Updating Packages
To update all packages to their latest allowed versions (respecting semver):
To update a specific package:
To check for outdated packages:
Uninstalling Packages
To remove a package:
This removes the package from node_modules and package.json. Shorthand:
NPM Scripts
NPM scripts allow you to define custom commands in your package.json file. This is a powerful feature for automating tasks.
Defining Scripts
Scripts are defined in the "scripts" section of package.json:
Running Scripts
To run a script:
For example:
Special Scripts
Some script names have special meaning and can be run without run:
Pre and Post Scripts
NPM automatically runs pre and post scripts if they exist:
Running npm start will execute all three scripts in order.
--. For example: npm start -- --port=3000 passes --port=3000 to your script.
Understanding package-lock.json
The package-lock.json file is automatically generated when you install packages. It serves several important purposes:
- Exact versions: Records the exact version of every installed package, including dependencies
- Consistency: Ensures all team members and deployment environments install identical versions
- Faster installs: NPM can skip some resolution steps when this file exists
- Security: Includes integrity hashes to verify package contents
package-lock.json to version control. It ensures reproducible builds across different environments.
NPX - Node Package Executor
NPX is a tool that comes with NPM (version 5.2+) that allows you to execute packages without installing them globally.
Benefits of NPX
- Run packages without global installation
- Always use the latest version of a package
- Execute packages from remote URLs
- Run different versions of the same package for testing
Using NPX
Instead of installing a package globally:
Running Local Binaries
NPX can also run locally installed packages:
Specifying Package Versions
You can run specific versions of packages:
Publishing Your Own Packages
NPM allows you to publish your own packages for others to use.
Prerequisites
- Create an NPM account at npmjs.com
- Login from the command line:
Preparing Your Package
Ensure your package.json has the required fields:
Publishing
To publish your package:
To update your package, increment the version number and publish again:
Best Practices for Package Management
1. Keep Dependencies Updated
Regularly check for and install updates to fix security vulnerabilities:
2. Use .npmignore
Create a .npmignore file to exclude files from your published package:
3. Specify Engine Requirements
Define the Node.js and NPM versions your package requires:
4. Use Lockfiles
Always commit package-lock.json to ensure consistent installations.
5. Clean Installs
For troubleshooting, use clean install which strictly follows the lockfile:
- Initialize a new project with
npm init -y - Install Express as a dependency
- Install Nodemon as a dev dependency
- Create custom scripts: "start" (runs with node) and "dev" (runs with nodemon)
- Test both scripts
- Use
npm list --depth=0to view your packages - Check for outdated packages with
npm outdated - Try using NPX to run a package without installing it:
npx cowsay Hello NPM!