A Beginner's Guide to Node Package Manager (NPM)

Jeetu DewanganJeetu Dewangan
8 min read

When we start building Node applications as beginners, many of us don't learn the details about Node Package Manager (in short, npm); we just focus on building the Node application, which I also used to do. But as I progressed in my career, I learned throughout the journey, diving deep into NPMโ€”like understanding what the package.json file is and how npm manages project dependency packages. In this blog, Iโ€™ll walk you through everything you need to know about NPM, from basic commands to best practices!


๐Ÿ—‚๏ธ The Role of package.json

At the center of every Node.js project lies a special file called package.json.

This file includes:

  • Project metadata (name, version, description)

  • List of project dependencies

  • Scripts to automate tasks

  • Project author and license information

In short, package.json keeps track of everything your project needs to run smoothly.

Tip: You can create a package.json file easily using:

npm init

When you run npm init, it will ask for some details like the project name, version, description, author, license, etc.

If you want to quickly create a package.json file with default values (skipping the questions), you can run:

npm init --yes

๐Ÿ“ฅ Installing Packages

The true power of Node.js comes from thousands of reusable packages.
Hereโ€™s how you can install them:

  • Install the latest version of a package:

      npm install <package-name>
    

    Example:

      npm install express
    
  • Install a specific version:

      npm install <package-name>@<version>
    

    Example:

      npm install express@4.17.1
    

All installed packages are saved in the node_modules folder and registered in the package.json automatically.


๐Ÿ› ๏ธ Development Dependencies

Sometimes, you need packages only during development, such as testing tools or linters.
In that case, you should install them as dev dependencies:

npm install <package-name> --save-dev

Example:

npm install nodemon --save-dev

or you can also use the short form -D:

npm install nodemon -D

This way, production servers wonโ€™t install unnecessary tools, making deployments faster and lighter.

๐Ÿ” How dev dependencies look inside package.json

After installing a development dependency like nodemon, your package.json will have a separate section called "devDependencies":

{
  "name": "node-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.2"
  }
}
  • Packages inside "dependencies" are needed for your app to run.

  • Packages inside "devDependencies" are only needed during development (not required in production).


โŒ Uninstalling Packages

Removing a package you no longer need is easy:

npm uninstall <package-name>

Example:

npm uninstall lodash

This command removes the package from both node_modules and your package.json.


๐Ÿ“ˆ Understanding Semantic Versioning (semver)

Node packages follow Semantic Versioning (semver) in the format:

major.minor.patch

Example: 2.3.1

Hereโ€™s what each part means:

  • Major version (2.x.x): Big changes that may break your existing code.
    (Example: Updating from 2.x.x to 3.0.0 might require code changes.)

  • Minor version (x.3.x): New features are added, but everything still works the same as before.
    (Example: Updating from 2.3.0 to 2.4.0 adds new features without breaking anything.)

  • Patch version (x.x.1): Only small bug fixes or improvements.
    (Example: Updating from 2.3.1 to 2.3.2 is safe and doesn't affect your code.)

Version Ranges in package.json

  • Caret (^): Allows updates to minor and patch versions without changing the major version.
    Example: "express": "^4.18.2" will update to any version <5.0.0.

  • Tilde (~): Allows updates to patch versions only.
    Example: "express": "~4.18.2" will update to any version <4.19.0.

  • Exact version: Installs a specific version.
    Example: "express": "4.18.2" will not update.

  • Latest version: Always installs the most recent version of the package, regardless of the current version range.
    Example: "express": "latest" will install the latest version available, even if it's a major version update.

Note:
semver helps you manage updates smartly. Use ^ for flexibility, ~ for stability, and exact versions for strict control over updates.


๐Ÿ“‹ Managing Installed Packages

Managing your project's dependencies is very important. NPM provides helpful commands for this:

  • List all top-level installed packages (direct dependencies):

      npm list
    

    This will show only the packages that are directly installed in your project (the ones you added via npm install).

  • List all packages including sub-dependencies:

      npm list --all
    

    This command lists every installed package in the project, including all nested dependencies, giving you a full view of your project's dependency tree.

  • Check for outdated packages (shows current, wanted, and latest versions):

      npm outdated
    

    This will tell you which packages are outdated and if updates are available, showing the current, wanted, and latest versions.

  • Update packages (updates the installed packages based on the allowed version range in package.json):

      npm update
    

    This updates all packages to the latest version allowed by the version rules you've set in your package.json. If you want to update to a new major version, you must manually modify package.json or install the specific version.

  • View detailed information about a package:

      npm view <package-name>
    

    This command shows detailed information about a package, such as its versions, description, maintainers, dependencies, and more. You can also use it to check for the latest version available.

Keeping your packages updated ensures your project remains secure and you benefit from new features and bug fixes!


๐ŸŒŽ Working with Global Packages

Some packages, like CLI tools (for example, nodemon, eslint, etc.), are better installed globally:

  • Install globally:

      npm install -g <package-name>
    
  • Uninstall globally:

      npm uninstall -g <package-name>
    

Global packages are available everywhere on your system, not just inside a project folder.


๐Ÿš€ Publishing Your Own Package

You can also publish your own package to the NPM registry! The basic steps are:

  1. Create an NPM account:
    Run the following command to log in to your NPM account:

     npm login
    
  2. Write your package:
    Create your package with the necessary files, including a package.json file that defines the package's metadata and version.

  3. Publish your package:
    To publish the package to the NPM registry, use the command:

     npm publish
    
  4. Updating your package:
    If you need to update your package with improvements or fixes, you can update the version number using the following commands:

    • Patch version: For bug fixes or minor improvements that are backward-compatible.

        npm version patch
      

      Example: 1.0.0 โ†’ 1.0.1

    • Minor version: For new features that are backward-compatible.

        npm version minor
      

      Example: 1.0.0 โ†’ 1.1.0

    • Major version: For breaking changes or major updates.

        npm version major
      

      Example: 1.0.0 โ†’ 2.0.0

The npm version command automatically updates the version in your package.json file, creates a Git commit, and tags the version if you're using Git. After updating the version, publish the updated package:

    npm publish

๐Ÿ›‘ Why node_modules Should Be Ignored

The node_modules folder contains all installed packages, but it can be very large.

Itโ€™s best practice to exclude node_modules from your version control (like GitHub) by adding it to your .gitignore file.

Instead, your teammates (or production server) will run npm install to regenerate the node_modules folder based on package.json.


๐Ÿ“ฆ How NPM Manages Packages and Dependencies

When you install a package using npm install <package-name>, NPM does two things:

  1. Installs the requested package.

  2. Automatically installs all of its dependencies (the packages it needs to work).

Sometimes, multiple packages you install might depend on the same package but require different versions.
Hereโ€™s how NPM handles this:

  • Different versions needed:
    NPM installs separate copies of the dependency inside each package's folder if the required versions are different.
    This ensures that every package gets exactly the version it needs.

  • Same version needed:
    If multiple packages require the same version of a dependency, NPM installs a single shared copy at the top level (inside node_modules) to avoid duplication and save space.

๐Ÿ“ Example folder structure:

node_modules/
  lodash/       (shared version)
  package-A/
    node_modules/
      lodash/   (different version needed by package-A)
  package-B/
    node_modules/
      lodash/   (different version needed by package-B)

โœ… Modern NPM (v7 and above) uses a nested + flattened structure with a smart algorithm to minimize duplication as much as possible, but still ensures all packages get compatible versions.

Note:
If conflicts can't be avoided, NPM installs separate versions locally inside the dependent package's own node_modules folder.


๐Ÿ“ Conclusion

NPM is an essential part of every Node.js developerโ€™s toolkit.
It simplifies working with open-source packages, keeps projects organized, and speeds up development.

By mastering NPM basics, you open the door to building powerful, efficient, and professional Node.js applications.


๐Ÿ“š Useful Commands Cheat Sheet

TaskCommand
Install a packagenpm install <package-name>
Install a specific versionnpm install <package-name>@<version>
Install a dev dependencynpm install <package-name> --save-dev
or npm install <package-name> -D
Uninstall a packagenpm uninstall <package-name>
List top-level installed packagesnpm list
List all installed packagesnpm list --all
Check for outdated packagesnpm outdated
Update installed packagesnpm update
Install a package globallynpm install -g <package-name>
Uninstall a global packagenpm uninstall -g <package-name>
View detailed info of a packagenpm view <package-name>
Initialize a package.jsonnpm init or npm init --yes
Publish a package to NPMnpm publish
Update package version (patch)npm version patch
Update package version (minor)npm version minor
Update package version (major)npm version major

๐Ÿ“ Final Words

So, that's my explanation of some of the most useful and commonly needed npm commands!
I hope this blog post helped you learn something new or made your npm journey a little smoother. ๐Ÿ˜Š

If you found this helpful, please like this blog post โ€” it really motivates me to create more content!
And if you know any other interesting npm tips or tricks beyond the ones I mentioned here, feel free to drop a comment below โ€” Iโ€™d love to learn from you too!

Thanks for reading! ๐Ÿ™
Happy Learning ๐Ÿš€

10
Subscribe to my newsletter

Read articles from Jeetu Dewangan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jeetu Dewangan
Jeetu Dewangan

I am a Software Developer.