If you have a lot of npm
packages installed globally and you want to remove them, here’s how you can do that without uninstalling them one by one:
$npm -g rm $(node -e "console.log(Object.keys(JSON.parse(process.argv[1]).dependencies).filter(p => p !== 'npm').join(' '))" "$(npm ls -g --json --depth 0)")
You might need to use sudo
if you don’t have the right permissions.
And below you can find the explanation of what this one line command is doing.
1. List the globally installed packages
This is how we can list the globally installed packages:
$# -g: list the global packages
$# --depth 0: list only the installed packages without their dependencies
$npm ls -g --depth 0
/usr/lib
├── create-react-app@3.4.1
├── gatsby-cli@2.12.1
├── http-server@0.12.0
├── live-server@1.2.1
└── npm@6.14.4
We can also show a parseable output instead of the tree view using the -p
flag:
$npm ls -gp --depth 0
/usr/lib
/usr/lib/node_modules/create-react-app
/usr/lib/node_modules/gatsby-cli
/usr/lib/node_modules/http-server
/usr/lib/node_modules/live-server
/usr/lib/node_modules/npm
But we’re going to use the JSON output that you can get with the --json
flag:
$npm ls -g --json --depth 0
{
"dependencies": {
"create-react-app": {
"version": "3.4.1",
"from": "create-react-app",
"resolved": "https://registry.npmjs.org/create-react-app/-/create-react-app-3.4.1.tgz"
},
"gatsby-cli": {
"version": "2.12.1",
"from": "gatsby-cli",
"resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.12.1.tgz"
},
"http-server": {
"version": "0.12.0",
"from": "http-server",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.0.tgz"
},
"live-server": {
"version": "1.2.1",
"from": "live-server",
"resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz"
},
"npm": {
"version": "6.14.4"
}
}
}
2. Get the package names
Since we’re using Node we’re going to use JavaScript to parse this output to get the package names instead of using awk
or grep
or any other tool.
If you want, you can check these options on this StackOverflow question .
We can execute JavaScript using Node’s -e, --eval
command line option:
$node -e "console.log('Hey there')"
Hey there
And we can get the command line arguments using process.argv
:
$node -e "console.log(process.argv)" one two
[ '/usr/bin/node', 'one', 'two' ]
So we can pass the JSON output of the npm ls
command as a command line argument:
$node -e "console.log(process.argv)" "$(npm ls -g --json --depth 0)"
[
'/usr/bin/node',
'{\n' +
' "dependencies": {\n' +
' "create-react-app": {\n' +
' "version": "3.4.1",\n' +
' "from": "create-react-app",\n' +
' "resolved": "https://registry.npmjs.org/create-react-app/-/create-react-app-3.4.1.tgz"\n' +
' },\n' +
' "gatsby-cli": {\n' +
' "version": "2.12.1",\n' +
' "from": "gatsby-cli",\n' +
' "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.12.1.tgz"\n' +
' },\n' +
' "http-server": {\n' +
' "version": "0.12.0",\n' +
' "from": "http-server",\n' +
' "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.12.0.tgz"\n' +
' },\n' +
' "live-server": {\n' +
' "version": "1.2.1",\n' +
' "from": "live-server",\n' +
' "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz"\n' +
' },\n' +
' "npm": {\n' +
' "version": "6.14.4"\n' +
' },\n' +
' }\n' +
'}'
]
Finally we can parse process.argv[1]
(The JSON string) and get the keys, and of course exclude npm
:
$node -e "
> // Parse the JSON string
> const json = JSON.parse(process.argv[1])
> // Get the keys (package names) and exclude 'npm'
> const pkgs = Object.keys(json.dependencies).filter(p => p !== 'npm')
> // Print to stdout the package names separated by spaces
> console.log(pkgs.join(' '))
> " "$(npm ls -g --json --depth 0)"
create-react-app gatsby-cli http-server live-server
This is the one line version:
$node -e "console.log(Object.keys(JSON.parse(process.argv[1]).dependencies).filter(p => p !== 'npm').join(' '))" "$(npm ls -g --json --depth 0)"
create-react-app gatsby-cli http-server live-server
3. Uninstall the packages
Now we have a string of the package names separated by spaces, we can pass this string to npm uninstall
:
$# `rm` is an alias of `uninstall`
$npm -g rm $(node -e "console.log(Object.keys(JSON.parse(process.argv[1]).dependencies).filter(p => p !== 'npm').join(' '))" "$(npm ls -g --json --depth 0)")
And this is a verbose version of the above one liner:
$# List of the installed packages as a JSON string
$JSON=$(npm ls -g --json --depth 0)
$# Script to parse the JSON and get the package names and exclude `npm`
$SCRIPT="console.log(Object.keys(JSON.parse(process.argv[1]).dependencies).filter(p => p !== 'npm').join(' '))"
$# Space separated string of the package names
$PKGS=$(node -e "$SCRIPT" "$JSON")
$# Uninstall the packages
$npm -g rm $PKGS