pnpm's blockExoticSubdeps setting lets only the dependencies you list in your root package.json come from exotic sources such as git repositories or direct tarball URLs. Every transitive dependency must resolve from the configured registry, local paths, workspace links or trusted GitHub repositories. It is on by default.
What counts as exotic
The pnpm docs list two kinds of exotic source:
- Git repositories, for example a git+ssh URL.
- Direct links to tarballs, for example an https URL ending in .tgz.
Both skip the registry. That matters because registry metadata, publish dates and provenance checks all assume a registry. A git dependency has none of that, and the code behind a branch name can change after you reviewed it.
Why the rule is about transitive dependencies
You choose your direct dependencies. You did not choose the dependencies of your dependencies, and a new release of a library can quietly add a git URL to its own manifest. Without a rule, your install would clone a repository you never heard of.
blockExoticSubdeps draws the line at ownership. The setting arrived in v10.26.0 with a default of true. Your root package.json can still use a git URL if you decide it should. A transitive package cannot.
What still resolves
According to the docs, transitive dependencies are allowed from:
| Source | Allowed for transitive deps |
|---|---|
| The configured registry | Yes |
| Local file paths | Yes |
| Workspace links | Yes |
| Trusted GitHub repositories (node, bun, deno) | Yes |
| Other git repositories | No |
| Direct tarball URLs | No |
What happens when it fires
The install fails for the offending dependency. You then have three honest choices:
- Ask the library maintainer to publish to the registry or drop the git reference.
- Replace the dependency with a registry version using an override.
- Add the package as a direct dependency yourself, after reviewing exactly which commit it points to, so the exotic source becomes a decision you own.
Option three changes the risk from invisible to reviewed, but it does not make the code safer by itself. Pin to a full commit hash, not a branch.
Finding the problem before you turn it on
Even with the default on, it helps to know where git dependencies live in your tree. Our post on how to find git URL dependencies in npm and pip projects shows searches you can run. For npm itself, the allow-git config controls whether git dependencies are fetched at all, and is covered in blocking git dependencies with npm allow-git.
Where Safeguard fits
A package manager setting stops an install. Safeguard's dependency scanning and SBOM generation record where each component in your lockfiles came from, so a reviewer can see a non-registry source in the inventory, and policies and gates can stop a pull request that introduces one.
Quick check
Is blockExoticSubdeps enabled by default?
Yes. The pnpm docs list the default as true, added in v10.26.0.
Can my own package.json still use a git dependency?
Yes. The setting restricts transitive dependencies only. Direct dependencies listed in your root package.json may use exotic sources.
Sources
Last reviewed: 19 October 2026.