Start trial
Plans & PricingContact Us
Log InStart For Free

A guide to npm: The node.js package manager

February 22nd, 2023

19 min read

npm logo appearing on a grid background.

Written by

Martin Gouws

Category

Developer Insights

Javascript is the most commonly seen language in web development. And while the multitude of resources that are available to devs is astounding, they’re matched by the millions of libraries.

When you first start using JavaScript libraries, they’re easy to maintain. Soon enough though, you’ll need a more mature solution – because libraries start depending on each other.

Enter the Node Package Manager (npm) – a JavaScript package manager used in conjunction with Node.js, although it can also be used independently. In short, npm gives you control over your project’s dependencies, and it’s a great way to contribute to the open-source world. 

As an example, TinyMCE has  an average of 30,000 deployments with npm per month (TinyMCE is just one of over 1.3 Million packages currently released online). 

This article explains:

  • Installing npm
  • Configuring npm
  • Useful commands, and 
  • Information on launching your own npm package. 

Read on to see the potential of npm, why it’s become the accepted way to keep track of libraries and how it combats dependency hell.

Install npm

Before you begin to run commands and get to installing packages, it’s a good idea to know how to check npm versions, and to check if you’re already running Node.js or npm is installed.

  1. Run the commands for node and npm with the “-v” verbose argument to check the version status:

node - v;
npm - v;
  1. If you don’t receive a version number, you can get Note and npm installed with the following commands:

npm install -g npm

This command installs Node.js, as well as the npm command line interface. 

How to install a specific version of npm

Want to install a specific version? No problem.

  1. Run npm install@[version-number] entering the specific version numbers after the “@” symbol. For instance:

npm install [package-name]@[version-number]

How to install a package globally

To install a package globally (like Mocha, or Angular-CLI) Add a “-g” argument like so:

npm install -g angular-cli mocha

How to install npm on Windows

For Windows environments, make use of the Windows installers. One project is NVM for Windows, which you can find on GitHub, and provides a solution for setting up npm on Windows. Another recommended installer is the Nodist project.

How to install npm on macOS

For macOS, there’s the nvm project for installing and making use of different versions of npm with the command line. The nvm syntax for macOS is slightly different to the npm commands shown in the preceding paragraphs. Take note of these commands: 

  • nvm ls-remote – lists available versions
  • nvm use node – makes use of node in a new shell when it is installed
  • nvm install – to get Node and your packages installed

How to install npm on Ubuntu

The npm documentation recommends making use of a NodeSource installer when working within Linux distributions. NVM, and another project called “n”, are designed to work in Unix and Unix-like environments, so these are also options for installing npm on Ubuntu. There are some official npm Frequently Asked Questions that can help explain some obstacles that might come up with using npm on Ubuntu.

How to reinstall npm

If you run into the error, and it looks like your npm version is unfixable, here’s how to remove it and start over:

  1. Locate the global npm folder. A command to do this:

npm list -g
  1. Once located, go to the folder location. The name of the folder to look for is node_modules. Look for a folder named “npm” inside node_modules, and then delete it

  2. Download the latest version of npm from GitHub in the form of a .zip file

  3. Unzip the file

  4. Extract the contents to the node_modules folder

  5. Rename the folder extracted from the zip file to “npm”, and skip any warnings

  6. Run npm i -g to update and reinstall npm. Delete any files that are listed in the command update as unnecessary.

How to uninstall npm

The main method to completely remove npm is to search the usr/local/lib folder in your operating system and remove any node or node_modules folders completely. Also:

  1. Check the usr/local/include folder for any node or node_modules folders

  2. Check usr/local/bin for any node executables and delete them

  3. Search the Home directory for any local, lib, or include folders and delete any node or node_modules folder.

  4. Remove any hidden .npm files inside the Home directory.

If you’ve made use of an installer like Brew for macOS, also run the brew uninstall node command. The StackOverflow answer from Dave Jarvis  and Dominc Tancredi has more information on completely uninstalling npm and Node.js

Note: Some uninstall procedures recommend running sudo rm -rf commands. Be very careful before running rm -rf commands with sudo. These commands can unintentionally delete folders without any consultation on the command line.

npm Commands

Ask a professional front-end developer, and they’ll say running npm commands on the command line (CLI) comprises most of the time that they spend interacting with npm. And the npm CLI help interface is actually, well, helpful.

  1. Query help (npm help) with the following:

npm help
  1. Read through the returned information the command spews out: it’s an entire array of options.

  2. Run “npm help-search” to see a list of search results direct from the npm markdown.

Useful npm commands

This is not an exhaustive list, but here are fourteen useful npm commands to know and run:

1. Install

The install command is a necessity. Use it to either install a new package locally or globally (when adding -g ), or to install dependencies listed in the package.json file (more on that later).

2. Uninstall

Also a necessity. Purge a specific package from the  node_modules directory either locally or globally (when adding -g) using this command.

3. Update

This usually follows the outdated command to update any outdated packages.

4. Access

In the context of npm-organizations, and private packages, this command belongs to those who have control of user permissions. That’s to say, the project administrators. (Seriously powerful stuff.) Used in conjunction with adduser, owner, team, etc. The command gives fine grained control over who has access to what in a node package.

5. Bin

Where in the directories are packages installed? Run this command to see an absolute file path.

6. Cache

If you start installing packages from npm left, right, and center, the cache command is quite useful.

  1. Call the command with the “ls” subcommand to  see a list of locally cached packages

  2. Call with the “clean” subcommand to clear all packages that are in the cache.

Back when the npm registry was still a bit unstable, this was essential to get back to a stable environment or to reset things when you didn’t properly set up npm permissions.

7. Config

We’ll get into the different configuration options later, but this command deals primarily with persisting configuration properties in the local or global configuration file by using the  set,  get or  delete subcommands.

8. Dedupe

Also called “ddp”, when working on a project over an extensive period of time, and installing packages straight from npm, this command will walk the local package tree and attempt to simplify dependencies.

9. ls

This command shows a package as a tree structure, depicting its dependencies and their dependencies. It’s cool to see and is also useful for comparisons with other projects.

10. Outdated

A great command used to evaluate the current state of installed dependencies and whether or not they’re outdated. In projects where the root dependency list is hundreds of lines long, a manual check on packages is close to impossible. Adding “-g --depth=0” to this command allows you to also check your globally installed packages.

11. Search

Use this to search the registry for all packages containing the text provided in the third argument.

12. Shrinkwrap

In short, this command allows you to lock down specific dependency versions in a package in order, so that a relaxed semver (semantic versioning) number doesn’t break production code.

13. Star

Do you really like the package you’re using? Use this command to show your appreciation directly from the terminal, which then reflects on the package’s page on the npm registry.

14. Version

This gives you a shorthand to bump the  package.json version property, and do a git tag all in one.

npm Configuration 

Configuration is a major part of npm. There are multiple ways you can configure npm, and they’re all important to know. The CLI is the main configuration method.

A typical setting: npm <command> --<configuration option> [<optional value>].

If there’s no value specified, the option sets to “true” by default.

An example of one npm configuration could be:

  • You’re developing your own npm package (more on that later)
  • You’re working on a scoped (private) npm package
  • The team you’re working with has decided to publish it as a public package.

This is done by appending --access=public to your publish command. If the option is not specified, the default would be restricted (private).

npm Configuration and environment variables

Configuration appended to CLI commands may not persist everywhere you need it to, and it can become tiresome to put together an array of configurations by the commands and options. In these cases, set configuration using environmental variables. On your development workstation, you can set environment variables as key and value pairs in config files that have the .env file type.

Any environmental variable set with the npm_config_ prefix will be used to configure npm. Here’s an example: 

export npm_config_registry=localhost:4321

This sets the registry configuration option globally. When you run an npm command, and the operating system executes the command, the npm registry location is set to localhost on port 4321, which is the specified value in the key and value pair.

npm Configuration and the npmrc file

You can also set configuration options using the special .npmrc file. When modifying configuration settings in the .npmrc file, rather than editing the file in a text editor, you can use the CLI by running a command in this format:

npm config set <key> <value>

For example, you can run npm config set access public to make the publishing configuration of a scoped (private) package persistently public (again, more on this later). By default, this command would persist the configuration locally (the user level configuration as described above), but you can add -g to make it persistent globally across all projects.

Note: When persisted configuration needs to happen on the project level, or on the built-in level, the .npmrc file must be modified using a text editor.

You can set up the .npmrc file to run at different levels depending on your requirements:

Project level

In the root of a project’s code along with its package.json file, typically path/to/project/.npmrc

User level

The directory that configures a specific user’s account, typically ~/.npmrc.

Global level

The directory where npm looks for global configurations, typically $PREFIX/etc/npmrc

Built-in level

This can typically be found at /path/to/npm/npmrc.

Note: Be cautious. This configuration is not only global, but it is also part of the npm source code, and best practice recommends (actually demands) that you don’t change code you’re not responsible for maintaining. 

npm Configuration with package.json

Another method for npm configuration involves settings made from the package.json file. However, this isn’t used very often in production, and should only be used if explicitly required. 

The preferred method is using a project level .npmrc file. The package.json file is essential for publishing your own project, and entering the npm registry. The file is where the management part of dependencies comes to life.

It has two required fields, namely name and version, and together these properties should be a unique identifier.

The name field should adhere to certain rules, as defined by the npm documentation on naming, and the version field is subject to the semver specifications.

npm Configuration: notable settings

The following settings are important to know for configuring npm.

npm Configuration for administration

  • access – Used to set permissions.
  • always-auth – It’s important to note that this setting defaults to false. When it’s set to true, npm will always require authentication when contacting the registry.
  • ca – Defaults to the npm certificate authority (CA). It can be changed to null to allow access to only known registrars, or to a specific CA certificate to only grant access to that specific one. This setting, along with cafile, cert and strict-ssl, are seldom used, but speak toward the security and reliability aspect of npm, allowing peace of mind in knowing that the package you are installing is coming from the source you expect.

npm configuration command outputs

  • color – This defaults to true, giving you a break from the standard bleakness of the terminal by coloring the stdout that is allowed by tty file descriptors. If set to false, the terminal remains dull. When it is set to always, it always outputs in color.
  • depth – This setting allows for granular control over what you see with recursive commands, such as ls and outdated, by assigning how deeply they’re executed. A value of 0 will only evaluate the first level of dependencies whereas infinity (the default) will cause all levels of dependencies to be evaluated. The exception to this rule is when using it with outdated; in that case, infinity is interpreted as 0 to ensure more relevant output.
  • loglevel – By default, this is set to warn, which gives an error and warning output when running npm commands. Other settings include silent, which provides no output; error, which only logs errors to the output; http, which only announces http request errors; info, for want informative output); verbose, which logs almost everything; and silly, which, like the name suggests, gives a silly amount of output and then some.
  • tag-version-prefix –The conventional default is v, specifying what is prepended to the git tag version when running “npm version”.

npm Configuration development options

  • dev – This is set to false by default, but when it’s set to true (when doing an npm install) all development dependencies in the package.json file will be installed along with the normal dependencies.
  • dry-run – When this setting is set to true, npm will not make any changes to your package but will instead tell you what it would have done. This can be very useful when running certain commands, such as dedupe or update.
  • git-tag-version – It is set to true by default. This setting tags a version in git when running the npm version command. If you are using npm as the package manager for a large project that’s tagged versions in git, it can save you time, and remember to update the package.json file for you.
  • production – When this is set to true, npm acts accordingly and runs all commands in production mode. This means that development or optional dependencies won’t be installed, nor will any development related tasks be executed.
  • rollback – When set to true, all failed installs are removed. This comes in handy when an installation of dependencies fails. Depending on how verbose and detailed your logs are, you should be able to see what installations failed, make a note of these, and run the npm install command with the rollback option set to true. Then with your notes and a dry-run installation (as described above), you can then debug the problem.

npm Configuration saving options

  • save – When installing a package directly from the registry, you can append –save to the command which adds the installed package to the dependencies option in the package.json file. For example, npm install lodash` will add lodash to your dependencies.
  • save-dev – Similar to the save configuration option, add --save-dev when installing a package, and it’s then added to the devDependencies option in the package.json file.
  • save-optional – Similar to the save configuration option, add --save-optional when installing a package, and it’s then added to the optionalDependencies option in the package.json file.
  • save-exact – When installing packages, the save, save-dev and save-optional options modify the package.json file by inserting the installed package into its respective property with a semver range operator. When invoking the ‘save-exact’ configuration setting with a value of true, in conjunction with one of the mentioned settings above, a specific version number is used, ignoring the semver range.
  • save-prefix – This sets the semver range operator when using save, save-dev or save-optional. The default is ^, allowing for minor upgrades on packages to happen on install. This can be set to any valid prefixed semver range operator.

How to update an npm version

You can also use npm to update itself.

  1. Run “npm install -g npm@latest”, and npm updates to the latest stable release.

Note: Each version of Node.js ships with a specific version of npm, and it’s best practice not to mess with that pairing too much. At the end of the day, stick with the pairing as they’re intended.

When using npm as a standalone tool, make sure you understand the implications of using whatever version you choose. There’s a great tool for managing different Node.js versions (and in turn npm versions) on the same system called nvm.

How to create your own npm package

The npm ecosystem is filled with packages, written by millions of different developers around the world. Each solves some sort of problem, providing an abstraction, or presenting an implementation of something. Chances are that, at some point, you too will want to develop your own package to share.

  1. Create a package.json file with the minimum required properties of “name” and “version”, and then the “main” property to specify the entry point, for example, index.js.

  2. Write your code in that index.js file

  3. Login with your npm user account, or create a new user from the terminal, and you’re ready to publish it to the npm registry.

How to publish an npm package: commands

1. Link

When you’re developing your own npm package, this allows you to create a symlink to the global context so it can be tested as if it was installed globally from the npm registry. For example, if you’re writing an assembly tool in a node that has a CLI installed globally, you can run this command and test your CLI’s behavior without needing to deploy it first.

2. Publish

This command is essential when developing your own package for npm. It does exactly as the name suggests; it publishes your package to the npm registry.

How to publish an npm package: the package.json

There are other notable options to add to your package.json file when you’re developing your own npm packages. The following list highlights some of these options:

1. main

This defines the entry point to your application, which defaults to index.js. Depending on convention or your framework, it might be app.jsor main.js. You can, of course, make it anything you want.

2. scripts

Scripts are an underrated property. First, it can be used to do things on prepublish. Second, it provides a place where you can alias an array of frequently used commands, ranging from build tasks (defined in gulp or grunt), triggering the installation of other dependencies (with something like bower), starting a development server with webpack, or running a set of bash commands.

3. dependencies

Dependencies is an option needed for a list of packages that’s needed by your application, along with the compatible semver number. It is a notable property because you can modify it with commands when you install local packages. This is done by adding --save (or the shorthand -S) at the end of the npm install command. When you do this, the newly installed package(s) gets added to the list of dependencies in your package.json file. 

Similarly, a dependency can also be removed by adding --save when running the npm uninstall command.

It’s important to be aware of the semver versioning patterns of each of the dependencies and what they mean. If the semver rule is too strict, you lose out on new features and improvements, whereas if the semver rule is too relaxed, a breaking version of a package can be installed along the line. A broken package install can prove to be quite difficult to resolve, especially when the minified version of the package is used.

4. devDependencies

Separate from the dependencies property, the “devDependencies” property allows you to define dependencies that are only used during the development phase and are not required for the production build (like ESLint, grunt-contrib packages, and Protractor). Just as with dependencies, this property can be modified from the terminal by adding --save-dev (or the shorthand -D) to the end of the npm install command or the npm uninstall command. 

The same caution applies to versioning as mentioned under dependencies.

5. bin

This is where you can specify your package’s executable file(s), like the path to a CLI utility. This property tells npm to create local or global symlinks to your executables when your package is installed.

6. config

As discussed earlier, this is where you define configuration settings though your package.json file.

7. private

When set to true, npm will refuse to publish the package. This should not be confused with the access configuration setting. The private option is a handy setting when you have a project that utilizes npm along with its package.json but it is not intended to be published to the npm registry, either scoped or public.

If your intention changes, simply change the setting to false, and you will be able to publish your package.

Custom properties

The package.json file also accepts custom properties, as long as the name isn’t already defined or reserved.

How to create a private npm package

Packages can be public or private:

  • Public packages are free to publish and are available for everyone to utilize.
  • Private packages, called scoped packages, can only be published if you’re a paid private modules user, and they can be identified by the distinct @username/ that is prepended to the package name.

Private (scoped) packages can also be published publicly by calling the publish command with --access=public.

Furthermore, if you spend some more time expanding and improving your package’s code base, and it’s time for a new version to be published, you simply alter the version (as per the semver rules and convention) of the package in the package.json file and type npm publish.

You can also use the command line interface and call npm version <update_type>, where update_type is either patch, minor, or major, as described by semver, and this then automatically increments the version number in the package.json file.

npm Organizations

Again, the npm documentation for this is excellent, and it would be futile to just repeat their words. 

What can be said about organizations in the npm context is that it’s extremely fine grained, and when managed correctly, large teams and individuals working on scoped or public packages under one name, can be very well managed and restricted. While it’s complex to master, it’s very rewarding.

The power of npm

Ultimately the documentation that npm provides is extensive and should be consulted for specifics, but this article provides a useful overview of both basic and more advanced, involved functionality, conveying the awesomeness of npm.

As with all things, strong opinions exist and many faults can be found. But if you’ve never tried npm (or node, for that matter), dive in, and explore it for yourself. Chances are you’ll enjoy it more than you think.

And if you’ve tested out npm by installing TinyMCE (npm -i tinymce 😉) you can explore the TinyMCE docs pages to learn how you can deploy TinyMCE in your environment with everyone's favorite Node.js package manager.

JavascriptNode.jsDevelopersProduct Development
byMartin Gouws

Martin is a young and talented JavaScript developer and software engineer who has his roots in enterprise Java. He has a mature understanding of the full SDLC and has helped build many applications from scratch for clients such as Anglo American. He has worked in corporate, as well as startup environments, and transparent communication is always prevalent in his work ethic. He is also an advocate of the Agile development mindset.

Related Articles

  • Developer InsightsNov 7th, 2024

    Meet the Top Experts at Frontend Nation 2024 with TinyMCE

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tiny logo

Stay Connected

SOC2 compliance badge

Products

TinyMCEDriveMoxieManager
© Copyright 2024 Tiny Technologies Inc.

TinyMCE® and Tiny® are registered trademarks of Tiny Technologies, Inc.