Yes, partly. With install-strategy set to linked, npm installs packages into a store and links only each package's declared dependencies, so an import of something you never listed fails during development. The npm docs recommend it for package authors, and also say it does not catch every case.
What a phantom dependency is
Under npm's default hoisted layout, packages are placed as high in node_modules as they can go. A transitive dependency of something you installed may land at the top, where your own code can import it even though it is not in your package.json. Your build passes. A user who installs your package alone does not get that transitive dependency, and your code fails for them.
It is a packaging bug with a security side. You depend on code whose version you never chose, and a change in someone else's tree can change what you import.
The four strategies
The npm config documents these values for install-strategy:
| Value | What it does |
|---|---|
| hoisted (default) | Installs non-duplicated packages at the top level, duplicated ones deeper as needed |
| nested | Installs in place with no hoisting (formerly legacy-bundling) |
| shallow | Installs only direct dependencies at the top level (formerly global-style) |
| linked | Installs into node_modules/.store and links in place, unhoisted |
Using linked to check your package
The npm developer guide suggests this while developing a package you plan to publish:
npm install --install-strategy=linked
npm test
The isolated layout only exposes a package's declared dependencies. An import of an undeclared package then fails for you in development, instead of resolving by accident.
What it does not catch
The docs include a note you should take seriously. A dependency that is still satisfied by a devDependency, or by the workspace root's node_modules, can resolve fine for you and still be missing for whoever installs your package. So linked mode is one check, not a guarantee.
To fill the gap:
- Run
npm pack --dry-runand inspect what ships. - Install the packed tarball into an empty folder and run your entry point.
- Compare imports in your source against the dependencies field, not devDependencies, for runtime code.
- Add the install and test step to CI so it is repeated.
Our post on phantom dependencies and how pnpm blocks them covers the same idea with pnpm's default layout, and npm-explain helps trace why something is present.
Trade-offs
Linked mode changes the node_modules layout, and some tools expect a flat tree. Try it in a branch before making it team policy. If a tool breaks, that is often the tool relying on an undeclared dependency, which is worth knowing.
Where Safeguard fits
Safeguard's dependency scanning and SBOM generation work from your lockfiles, so declared and resolved components both show up in the inventory, and reachability analysis helps separate vulnerable code you call from code you do not. A free scan is at https://gold.safeguard.sh/scan.
Quick check
What is the default npm install strategy?
hoisted. Linked is an opt in value that installs into node_modules/.store and links packages in place.
If linked mode passes, can I publish safely?
Not on that evidence alone. The npm docs say a dependency satisfied by a devDependency or the workspace root can still be missing for your users, so also test the packed tarball in a clean folder.
Sources
Last reviewed: 19 October 2026.