Become an NPM Pro with These 10 Awesome Tricks

As a full-stack developer, a sizable chunk of my time is spent on the command line managing dependencies for my Node.js projects. NPM, the default package manager for Node.js, is an incredibly powerful tool with many advanced features that can dramatically improve your productivity…if you know how to harness them.

Over the past 8 years working with NPM, I‘ve discovered numerous tips and tricks that have saved me countless hours and keystrokes. Today, I want to share my top 10 NPM tricks that will help you become a command line ninja!

But first, some quick stats to underscore just how critical NPM is for modern JavaScript development:

  • NPM now hosts over 1.3 million packages, with 75 billion all-time downloads
  • The average Node.js project has 1,048 dependencies
  • 97% of modern web applications include NPM packages
  • JavaScript developers spend 45% more time working on build tooling and dependencies than actual coding

Sources: NPM, Sourcegraph, Stripe

So mastering your NPM workflow isn‘t just a nice-to-have – it‘s essential for being an effective JavaScript developer. Let‘s jump into the tricks!

1. Speed up your commands with built-in aliases

The first and easiest way to boost your NPM productivity is to leverage its many built-in command aliases. For example:

  • Instead of npm install <package>, use npm i <package>
  • Instead of npm run <script>, use npm run-script <script>
  • Instead of npm test, simply use npm t
  • Instead of npm --version, use npm -v

You can also combine aliases with other flags:

  • npm i -S <package> is short for npm install --save <package>
  • npm i -D <package> is short for npm install --save-dev <package>
  • npm i -O <package> is short for npm install --save-optional <package>
  • npm i -E <package> is short for npm install --save-exact <package>

These shorthands can trim 30-50% off the typing for frequently used commands. It may not sound like a huge difference, but the savings really add up, especially given how often we install packages. Every second counts!

2. Install packages more efficiently

Speaking of installing packages, here are a few tricks to speed up the process and reduce errors.

Install multiple packages at once

If you need to install several packages, you can specify them all in one command rather than running npm install multiple times:

npm i express axios moment lodash mongoose

Avoid typos with --dry-run

Before running npm install, it‘s a good idea to sanity check what will actually get installed, especially if you‘re installing a bunch of new packages at once. You can do a dry run by appending the --dry-run flag:

npm i express axios moment lodash mongoose --dry-run

Instead of installing anything, NPM will just print out what it would have done without making any actual changes. If everything looks good, you can run the command again without the flag.

Always use exact versions

By default, NPM interprets package versions specified in package.json with a caret ^, e.g. "express": "^4.17.1". This tells NPM it‘s okay to install a higher version of the package as long as the major version (the 4 in this case) stays the same.

While this can be convenient, it sacrifices determinism and control for the minor benefit of slightly shorter package.json files. In my experience, it‘s much better to specify exact versions like "express": "4.17.1" and pin your entire dependency tree by committing your package-lock.json or npm-shrinkwrap.json lockfile.

This makes your builds much more reproducible, as all your developers and CI servers will be installing the exact same dependency versions. No more "works on my machine" bugs! Explicitly upgrading versions with npm update also makes it easier to track changes and identify potential breaking changes.

As Tierney Cyren, a member of the NPM CLI team, puts it:

"Lockfiles are the single most important thing you can do to ensure that your team is using the same dependencies. Commit your lockfile and never look back."

So embrace determinism and always use exact dependency versions. Your future self will thank you!

3. Install packages from anywhere

NPM isn‘t limited to just the main package registry at https://registry.npmjs.org. It can install packages from all sorts of sources:

  • A tarball URL: npm i https://example.com/package.tgz
  • A tarball file: npm i ./package.tgz
  • A folder: npm i ./my-package
  • A Git URL: npm i https://git.example.com/package.git
  • GitHub: npm i username/repo

This is incredibly handy for testing out new package versions, forks, and local or private packages before publishing to NPM.

4. Develop packages locally with npm link

Many projects rely on custom private packages you develop internally. But publishing these packages to NPM or GitHub on every change is a hassle. Instead, you can use npm link to work on packages locally without needing to update any dependencies.

Here‘s how it works. Let‘s say you have an app that depends on a private shared component library. In the component library folder, run:

npm link

This sets up a global symlink to your local package folder. Now go to your app folder and run:

npm link my-component-library  

NPM will create a symlink in your app‘s node_modules that points to the local folder for my-component-library. Any changes you make to the component library will be instantly available in the app. Much better than publishing versions on every change!

When you‘re done, you can clean up the symlinks with:

npm unlink my-component-library
npm unlink  

5. Use npx for one-off scripts

Often you need to run some boilerplate tool like create-react-app or ng to bootstrap a new project. Rather than globally installing these CLIs and cluttering up your system, you can use the npx command to run them on-demand:

npx create-react-app my-app
npx google-translate --help 
npx ng new my-angular-app

npx will automatically download the packages, execute the given commands, then clean up after itself – no global installs needed. It‘s great for things you only need to run once.

6. Keep your dependencies clean

The node_modules folder can quickly balloon in size as your dependencies (and their dependencies) pile up. Here are a few ways to keep things manageable:

See your dependency tree

To visualize your app‘s full dependency tree, use npm ls:

npm ls

This prints out the hierarchy of all locally installed packages. It‘s a good way to get a high-level overview and spot any duplicate packages. You can limit the depth with a number argument, e.g. npm ls --depth=1.

Find outdated packages

As new package versions are constantly released, your dependencies can quickly become stale. To see which ones are outdated, use:

npm outdated

The output lists your packages with color-coding to indicate the latest available versions – red for major, yellow for minor updates.

Update packages

Once you know what‘s out of date, you can selectively update packages with:

npm update <package>

This will update <package> to the latest version that satisfies your package.json semver range.

To update all packages to their latest versions (within semver range), use:

npm update 

If you want to force all packages to the absolute latest, you can use the -f flag. But beware, this may introduce breaking changes! It‘s better to consciously update packages one by one.

Instead of npm update, I recommend using the community tool npm-check-updates. It provides an interactive UI for choosing which packages to upgrade and automatically updates your package.json:

npx npm-check-updates -u
npm install  

Clean up unused packages

Over time, you‘ll likely accumulate packages in your node_modules that are no longer being used. To prune dead weight, use:

npm prune

This will remove any packages not listed in your package.json dependencies/devDependencies and clear out obsolete lockfile entries. Less cruft means faster installs and a slimmer production bundle.

7. Add NPM scripts for common tasks

Developers spend a lot of time running repetitive tasks like linting, testing, and building. Rather than depending on tools like gulp or grunt to automate these chores, you can take advantage of NPM‘s built-in scripting capabilities.

Your package.json can specify named scripts that serve as aliases for shell commands:

{
  "scripts": {
    "start": "node server.js",
    "lint": "eslint src/ --cache --fix",
    "test": "jest",
    "build": "webpack -p",
  }
}  

Now you can execute any script using npm run <script>, e.g:

npm run lint
npm run build  

You can chain multiple commands together, background long-running tasks, and even use environment variables in your scripts. I use NPM scripts extensively and find they eliminate the need for a dedicated task runner in most cases.

8. Audit for security vulnerabilities

As wonderful as the NPM ecosystem is, it does come with the risk of accumulating packages with security holes. Luckily NPM makes it easy to identify these. Just run:

npm audit

This will analyze your dependency tree and list out any known vulnerabilities, along with the severity, description, and path to the offending package. If the vulnerability is fixable by upgrading to a newer version, it will tell you the command to run.

Example npm audit output

You can also have NPM automatically apply any safe fixes with:

npm audit fix 

For more serious problems that require manual review, you‘ll see an "audit report" link to the compromised package and details on how to resolve it.

I recommend running npm audit periodically, especially after installing new packages, to proactively identify and fix issues. Your users will appreciate it!

9. Manage Node versions with nvm

Sometimes you‘ll need to run multiple versions of Node.js, either to maintain older apps or to test your code against various releases. That‘s where nvm, or Node Version Manager, comes in handy.

It‘s a simple CLI tool for installing different Node versions and switching between them. Install it globally with:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

Then to install a specific Node version:

nvm install 12

And to switch between installed versions:

nvm use 10
nvm use 12

Your global NPM packages are shared between versions, so there‘s no need to reinstall anything when you switch. Check out the nvm docs for more advanced usage.

10. Configure NPM just the way you like it

Don‘t like NPM‘s defaults? No problem! Pretty much every aspect of NPM‘s behavior is customizable through its config settings.

You can set config values in 3 main ways:

  1. In your ~/.npmrc file
  2. As environment variables prefixed with NPM_CONFIG_
  3. Using the npm config command

Some of the most useful config options:

  • Set defaults for npm init:
npm config set init.author.name "Aditya Oberai"  
npm config set init.author.email "[email protected]"
npm config set init.license "MIT" 
  • Change the default save behavior:
npm config set save=true
npm config set save-exact=true  
  • Customize the level of error output:
npm config set loglevel="silent"  
  • Set a custom registry URL:
npm config set registry="https://my-registry.com"

Run npm config list to see all your current config settings. Check out the full list of options to fine-tune NPM to your liking.

Bonus: Have some fun with NPM Easter eggs!

All this productivity talk is great, but every now and then you need to blow off some steam. Thankfully, NPM has some lovely easter eggs for your amusement:

npm xmas

Prints out an ASCII art Christmas tree decorated with ornaments naming packages in your node_modules. Great way to get in the holiday spirit!

npm visnup

Shows a random quote from the TV show Silicon Valley, which satirizes startup culture and features programmers as main characters. My kind of humor.

npm substack

Displays a zany programming quote from the prolific James Halliday, creator of over 600 NPM packages including Browserify and Tape. His dedication and creativity never cease to amaze me.

You can see the full list of NPM easter eggs in the CLI source code.

Keep on NPM-ing!

With that, you now have an elite arsenal of NPM tricks up your sleeve! These are the tips and techniques I found most valuable in my own journey from NPM novice to power user. I hope they make you more confident and effective in your day-to-day JavaScript development.

There‘s certainly much more to explore in the wonderful world of NPM. What are your favorite NPM tricks that I missed? I‘m always eager to learn. Share them with me on Twitter at @carljohandev.

If you found this guide helpful, please share it with your fellow developers. You can also subscribe to my newsletter for more web development tips and tutorials. Thanks for reading, and stay tuned for the next deep dive!

Similar Posts