NPM best practices: Stop installing npm packages globally

There is almost no use in installing npm packages globally. Here's why

Pile of cluttered parcels: what happens when you install every npm package globally

A few years back when I started using npm, I didn’t mind installing many packages globally. Nowadays, I see almost no use in installing npm packages globally.

Let me tell you why globally installed packages aren’t that great and what you should do instead.

Issues with globally installed npm packages

In a previous article, I’ve explained why freezing the versions of node and npm is really useful for any project. As a matter of fact, freezing the versions of your project dependencies is even more important.

Often times though, people seem to only think about actual project dependencies as requiring a stable version. Utilities are often forgotten/neglected. Still, the different build/dev tools matter a lot for the stability and to limit the “it works on my machine” syndrome.

If the tools required to build/run your project aren’t part of your package.json file, then it means that you have to maintain separate documentation. First off, this creates friction for anyone joining the team. This alone is a good enough reason to list the build/dev dependencies as well. In addition, it’s easy to forget updating the documentation, leaving it out of sync and potentially inducing future time waste.

Another point is that globally installed packages are like installed applications. After some time, you tend to forget why they’re even there. If some of your projects require them, then you risk not being able to work on those projects anymore. If instead those packages are listed in the project’s dependencies, then it’s alright: do an install and you’re good to go.

Alternatives

For projects relying on npm, the simplest alternative is to add all of the tooling to the devDependencies of the project’s package.json file. That way, whenever you install the project, you also get all the tools that you need. If you do that, then using those tools in npm scripts is as natural as if they were installed globally, since the contents of node_modules/.bin are added to the “path” visible to scripts.

I’ll probably write an article about npm scripts one of these days, since I rely a lot on them. They help me introduce “shared commands” for the whole team. Thanks to devDependencies and npm scripts, every team member has access to the same build/tools/commands, which is really valuable. To me that’s like a more modern/user friendly Makefile ;-)

Another thing that you can do when you think about installing a package globally is to use npx instead. The npx command comes along with npm and allows to easily execute npm binaries.

npx works as follows: it first checks the current path (including the local node_modules/.bin folder) to find the command that you’re trying to invoke. If it finds it in “node_modules/.bin”, then it executes that (that means that if your build tool/cli is part of your dependencies, then npx will find it).

If npx doesn’t find the command in the current path (whether locally or globally / in the npm cache), then it will try to install it before executing it. npx usually does a good job at finding what to install. If it fails though, you can help it using the “--package” flag. Of course you can leverage bash aliases for this ;-)

Note that you can easily get rid of the wasted space generated by npx by clearing your npm cache.

TLDR;

devDependencies + npm scripts have tons of benefits for stability, limiting configuration drift, avoiding needless documentation, removing headaches and helping everyone share the same environment

npx can be used to avoid installing packages globally and you only need to clean the npm caches to remove the clutter

Conclusion

In this article, I’ve shared a few thoughts about why I almost never install npm packages globally. Answers may be different if you’re using yarn, but the general idea should be similar. Globally installed packages are like global variables: pollution! ;-)

That's it for today! ✨


Go Further

NodeJS best practice for production: Use stable node and npm versions across your projects and teams
Use stable versions of Node.js and npm to avoid surprises in production
Git tutorial for beginners — Part 4: Branches
Let’s now learn about Git branches!
Git tutorial for beginners — Part 3: Commits, log and amend
Discover how to create and modify commits with Git, but also how to look at the commit log

Want to go deeper?

Knowii Community - Master Knowledge Management + AI | From €4.99/month
Join 400+ members mastering Knowledge Management AND AI. Community + Courses + Tools integrated. €500+ value in Knowledge Master tier.

About Sébastien

I'm Sébastien Dubois, and I'm on a mission to help knowledge workers escape information overload. After 20+ years in IT and seeing too many brilliant minds drowning in digital chaos, I've decided to help people build systems that actually work. Through the Knowii Community, my courses, products & services and my Website/Newsletter, I share practical and battle-tested systems.

I write about Knowledge Work, Personal Knowledge Management, Note-taking, Lifelong Learning, Personal Organization, Productivity, and more. I also craft lovely digital products and tools.

If you want to follow my work, then become a member and join our community.

Ready to get to the next level?

Looking for the right tools?

Found this valuable? Share it with someone who needs it.

Join 6,000+ readers. Get practical systems for knowledge & AI. Free.

Subscribe ✨

Free: Knowledge System Checklist

A clear roadmap to building your own knowledge system. Subscribe and get it straight to your inbox.

6,000+ readers. No spam. Unsubscribe anytime.