By default, every npm install you run installs a package locally — tucked inside that one project's node_modules folder, usable only from within that project. Most of the time that's exactly right. But some packages aren't meant to be imported into code at all — they're command-line tools you want available everywhere on your machine. That's what global installation is for.
The flag that changes everything: -g
npm install -g <package-name>
Instead of writing into your current project's node_modules, this installs the package into a single, shared location on your system and — critically — makes its command-line executable available from any terminal, in any folder, without cd-ing anywhere first.
A concrete example
nodemon is a tool that watches your files and restarts your server automatically whenever you save a change. It's not something your application code ever require()s — you just want to type nodemon from a terminal and have it work.
npm install -g nodemon
Now, from literally any project folder on your computer:
nodemon server.js
nodemon will start your server and keep watching for file changes, restarting automatically each time you save.
Where global packages actually live
The exact folder depends on your operating system — commonly /usr/local/lib/node_modules on macOS and Linux, and inside %AppData%\npm\node_modules on Windows. You rarely need to know this, but if you're curious, npm will tell you directly:
npm config get prefix
Checking what's installed globally
npm list -g --depth=0
The --depth=0 keeps the output to just the top-level packages, skipping their internal dependency trees, which makes the list actually readable.
Removing a global package
npm uninstall -g nodemon
The rule of thumb for choosing local vs. global
| Situation | Install |
|---|---|
Your code will require() or import it | Local |
| It's a command-line tool you'll run from anywhere | Global |
| Different projects might need different versions of it | Local (global installs give you exactly one shared version) |
| It needs to be listed in package.json so teammates get it automatically | Local |
Why experienced developers lean local
Global installs feel convenient at first, but they quietly cause a specific kind of pain: two different projects on the same machine, each expecting a different version of the same global tool, will fight over that one shared installation. A newer teammate who clones your project also won't automatically get whatever you installed globally, since it's invisible to package.json. For that reason, many teams install even CLI tools locally and reach them through an npm script:
"scripts": {
"dev": "nodemon server.js"
}
This way, running npm run dev uses the project's own local copy of nodemon — version-locked, listed in package.json, and identical for every person on the team. Global installs still have their place for tools you genuinely use the same way across every project (npm, project scaffolding CLIs, and the like) — but for anything project-specific, local is usually the safer default.