npm prune is a surprisingly powerful command for cleaning up your Node.js project, but it’s not just about deleting packages. It’s fundamentally about ensuring your project’s dependencies accurately reflect its runtime needs.
Let’s see it in action. Imagine you have a project with a package.json that looks something like this:
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.17.1",
"lodash": "^4.17.21",
"moment": "^2.29.1"
},
"devDependencies": {
"jest": "^27.0.6",
"eslint": "^7.32.0"
}
}
You’ve been developing this app, and maybe you installed moment for some date formatting, but then you realized Express has built-in date handling that’s good enough. Or perhaps you installed lodash for a specific utility, but you only used it once, and now it’s just sitting there. You also have development dependencies like jest for testing and eslint for linting.
Now, let’s say you want to deploy this application. You don’t need jest or eslint to run your application in production. They are only needed for development and testing. If you were to simply run npm install in a fresh environment based on this package.json, both production and development dependencies would be installed. This bloats your node_modules directory, increases install times, and can even subtly introduce issues if there are version conflicts or unexpected side effects.
This is where npm prune comes in. When you run npm prune within your project directory, it does something specific: it removes packages that are not listed as direct dependencies in your package.json but are present in your node_modules folder. Crucially, it respects the NODE_ENV environment variable.
If NODE_ENV is set to production, npm prune will remove all packages that are listed under devDependencies in your package.json. It also removes any packages that are not directly or indirectly required by your dependencies.
Let’s simulate this. Suppose you’ve already run npm install and your node_modules directory is full of everything from express to jest.
First, set your environment to production:
export NODE_ENV=production
Then, navigate to your project directory and run:
npm prune
After this command, if you check your node_modules directory, you’ll notice that jest and eslint (and any packages they might have pulled in that aren’t needed by your production dependencies) are gone. The lodash and moment packages, however, will likely remain because they are listed under dependencies in your package.json.
If you were to run npm prune without setting NODE_ENV to production (or if NODE_ENV is not set at all, which defaults to development for most npm operations), it will only remove packages that are not required by any dependency (either direct or transitive) listed in your package.json. This is useful for cleaning up orphaned packages that might have been installed as peer dependencies or as a result of previous, now-removed, dependencies.
The real magic happens when you combine npm prune with npm install --production. When you deploy your application to a production server, you typically don’t want your development tools. The standard practice is to:
- Copy your project code (including
package.jsonandpackage-lock.json) to the production server. - Set the environment variable:
export NODE_ENV=production. - Run
npm install --production. This command installs only the packages listed underdependenciesinpackage.jsonand their transitive dependencies. It completely ignoresdevDependencies. - Then, if you run
npm pruneafternpm install --production, it will remove any other extraneous packages that might have somehow ended up innode_modules(thoughnpm install --productionis usually quite clean on its own).
A common misconception is that npm prune modifies your package.json or package-lock.json. It does not. It operates solely on the node_modules directory. Its purpose is to ensure that the installed dependencies match what’s declared, and, when NODE_ENV=production, to ensure only production-ready packages are present.
The command npm prune --production is a shorthand for export NODE_ENV=production && npm prune. It’s a convenient way to achieve the same result.
The next step after ensuring your dependencies are pruned for production is often to analyze your dependency tree for security vulnerabilities.