This article is based on Node v18.13.0
Installing and uninstalling dependencies are a core part of working with any Node.js project or framework React, Angular, NextJS, Express, Vue, etc. But how do you list your installed dependencies? If you are just starting with Node.js, have a look at the NodeJS intro article install node packages.
If you work on different projects with different environments and different node versions, surely, some effort is needed to manage this, and version conflicts are anything but nice. For example, globally installed dependencies, can cause version issues in your project, if you use a wrong version. Or you are currently in the process of a major update in a project, and try to upgrade the dependencies, and all of a sudden you get an error when installing. Most likely, npm ERR! Invalid version
in the log after running npm install
. Then you have to start to debug and the fun starts.
How to fix version conflicts in installed NPM Packages?
The first step when facing version issues with installed packages is to delete and reinstall.
- Clean the
node_modules
folderrm -r node_modules
- Re-install packages with
npm install
If the issue still persists clean NPM cache. You can forcefully clean the NPM cache with npm cache clean --force
In a lot of cases, the issue is resolved now. If it isn't, you have to start debugging. First you have to list your installed packages
How to list installed NPM Packages?
The first step is the NPM, you are going to look for the npm ls
command.
The npm ls [[<@scope>/]<pkg> ...]
will print to stdout all the versions of packages that are installed, as well as their dependencies when --all is specified, in a tree structure.
Let's create a small project and see what it prints out to stdout. Create a project with npm init and install a single dependency express
.
mkdir npm-ls-test
cd npm-ls-test
npm init -y
npm i express
If you then run npm ls
in the sample project folder, you will get the entire packages installed, when you install express
.
npm-ls-test@1.0.0
└─┬ express@4.18.2
├─┬ accepts@1.3.8
│ ├─┬ mime-types@2.1.35
│ │ └── mime-db@1.52.0
│ └── negotiator@0.6.3
├── array-flatten@1.1.1
├─┬ body-parser@1.20.1
│ ├── bytes@3.1.2
│ ├── content-type@1.0.5 deduped
│ ├── debug@2.6.9 deduped
│ ├── depd@2.0.0 deduped
│ ├── destroy@1.2.0
│ ├── http-errors@2.0.0 deduped
│ ├─┬ iconv-lite@0.4.24
│ │ └── safer-buffer@2.1.2
│ ├── on-finished@2.4.1 deduped
│ ├── qs@6.11.0 deduped
│ ├─┬ raw-body@2.5.1
│ │ ├── bytes@3.1.2 deduped
│ │ ├── http-errors@2.0.0 deduped
│ │ ├── iconv-lite@0.4.24 deduped
│ │ └── unpipe@1.0.0 deduped
│ ├── type-is@1.6.18 deduped
│ └── unpipe@1.0.0
├─┬ content-disposition@0.5.4
│ └── safe-buffer@5.2.1 deduped
├── content-type@1.0.5
├── cookie@0.5.0
├── cookie-signature@1.0.6
├─┬ debug@2.6.9
│ └── ms@2.0.0
├── depd@2.0.0
├── encodeurl@1.0.2
├── escape-html@1.0.3
├── etag@1.8.1
├─┬ finalhandler@1.2.0
│ ├── debug@2.6.9 deduped
│ ├── encodeurl@1.0.2 deduped
│ ├── escape-html@1.0.3 deduped
│ ├── on-finished@2.4.1 deduped
│ ├── parseurl@1.3.3 deduped
│ ├── statuses@2.0.1 deduped
│ └── unpipe@1.0.0 deduped
├── fresh@0.5.2
├─┬ http-errors@2.0.0
│ ├── depd@2.0.0 deduped
│ ├── inherits@2.0.4
│ ├── setprototypeof@1.2.0 deduped
│ ├── statuses@2.0.1 deduped
│ └── toidentifier@1.0.1
├── merge-descriptors@1.0.1
├── methods@1.1.2
├─┬ on-finished@2.4.1
│ └── ee-first@1.1.1
├── parseurl@1.3.3
├── path-to-regexp@0.1.7
├─┬ proxy-addr@2.0.7
│ ├── forwarded@0.2.0
│ └── ipaddr.js@1.9.1
├─┬ qs@6.11.0
│ └─┬ side-channel@1.0.4
│ ├─┬ call-bind@1.0.2
│ │ ├── function-bind@1.1.1
│ │ └── get-intrinsic@1.2.1 deduped
│ ├─┬ get-intrinsic@1.2.1
│ │ ├── function-bind@1.1.1 deduped
│ │ ├─┬ has@1.0.3
│ │ │ └── function-bind@1.1.1 deduped
│ │ ├── has-proto@1.0.1
│ │ └── has-symbols@1.0.3
│ └── object-inspect@1.12.3
├── range-parser@1.2.1
├── safe-buffer@5.2.1
├─┬ send@0.18.0
│ ├── debug@2.6.9 deduped
│ ├── depd@2.0.0 deduped
│ ├── destroy@1.2.0 deduped
│ ├── encodeurl@1.0.2 deduped
│ ├── escape-html@1.0.3 deduped
│ ├── etag@1.8.1 deduped
│ ├── fresh@0.5.2 deduped
│ ├── http-errors@2.0.0 deduped
│ ├── mime@1.6.0
│ ├── ms@2.1.3
│ ├── on-finished@2.4.1 deduped
│ ├── range-parser@1.2.1 deduped
│ └── statuses@2.0.1 deduped
├─┬ serve-static@1.15.0
│ ├── encodeurl@1.0.2 deduped
│ ├── escape-html@1.0.3 deduped
│ ├── parseurl@1.3.3 deduped
│ └── send@0.18.0 deduped
├── setprototypeof@1.2.0
├── statuses@2.0.1
├─┬ type-is@1.6.18
│ ├── media-typer@0.3.0
│ └── mime-types@2.1.35 deduped
├── utils-merge@1.0.1
└── vary@1.1.2
Without an argument npm ls
lists all the dependencies down the dependency tree. If you are just interested in for example serve-static
, you have to add an argument in the format name@version-range
. Hence, you would do npm ls serve-static@1.15.0
. The stdout will be only for this package.
npm-ls-test@1.0.0
└─┬ express@4.18.2
└── serve-static@1.15.0
If you want to specify the depth in the dependency tree, add an argument for depth
. The default level is infinity, which makes the stdout quite long. The stdout for npm-ls-test npm ls --depth=1
, is only one level deep.
npm-ls-test@1.0.0
└─┬ express@4.18.2
├── accepts@1.3.8
├── array-flatten@1.1.1
├── body-parser@1.20.1
├── content-disposition@0.5.4
├── content-type@1.0.5
├── cookie@0.5.0
├── cookie-signature@1.0.6
├── debug@2.6.9
├── depd@2.0.0
├── encodeurl@1.0.2
├── escape-html@1.0.3
├── etag@1.8.1
├── finalhandler@1.2.0
├── fresh@0.5.2
├── http-errors@2.0.0
├── merge-descriptors@1.0.1
├── methods@1.1.2
├── on-finished@2.4.1
├── parseurl@1.3.3
├── path-to-regexp@0.1.7
├── proxy-addr@2.0.7
├── qs@6.11.0
├── range-parser@1.2.1
├── safe-buffer@5.2.1
├── send@0.18.0
├── serve-static@1.15.0
├── setprototypeof@1.2.0
├── statuses@2.0.1
├── type-is@1.6.18
├── utils-merge@1.0.1
└── vary@1.1.2
If you have found the culprit package, which causes the version conflict, and re-installing and cleaning the cache didn't resolve it, you can use the overrides
section in the package.json
to make changes to a specific package, see NPM.
For example, we want to use a specific version for super-nice-package
, we can simply add the following code to the package.json.
{
"overrides": {
"super-nice-package": "12.15.1"
}
}
Version conflicts can also arise when for example a maintainer of a package is lacking a bit behind another major package. Usually, after some time, the maintainer updates it, and the version conflicts get resolved, but until this happens, you can use the overrides
method.
Be aware , to regularly update your project, and remove the overrides , if possible.
How to list installed globally packages?
You can list globally installed packages with npm ls --global
or npm ls -g
.
For example, if you use nvm
, the output should look something like this. In this example I used npm ls -g --depth=0
to list my global installed packages.
/PATH/.nvm/versions/node/v18.13.0/lib
├── @angular/cli@15.1.4
├── corepack@0.15.2
├── gatsby-cli@5.8.0
├── npm@8.19.3
└── serve@14.2.0
Please be aware, that if you have to change a globally installed package for whatever reason (update cycle, security fixes, license updates, etc.) within a team of multiple developers, you have to communicate this to every relevant person.
TL;DR
- The NPM CLI has a built-in command to list dependencies
npm ls
. - You can use the
overrides
section in thepackage.json
to override specific dependencies. - When facing version conflicts, remove and reinstall dependencies, and/or forcefully clean the npm cache to fix it.
Thanks for reading and if you have any questions , use the comment function or send me a message @mariokandut.
If you want to know more about Node, have a look at these Node Tutorials.
Top comments (0)