Advanced Features
Advanced cleanup, patch tracking, and override management workflows
Advanced cleanup, patch tracking, and override management workflows
Pastoralist supports npm's nested override syntax for transitive dependencies.
When you need to override a transitive dependency, you can use nested overrides:
{ "dependencies": { "pg": "^8.13.1" }, "overrides": { "pg": { "pg-types": "^4.0.1" } }}This tells npm to use pg-types@^4.0.1 whenever pg requests pg-types,
regardless of the version range declared by pg.
You can override multiple transitive dependencies:
{ "overrides": { "pg": { "pg-types": "^4.0.1", "pg-protocol": "^1.6.0" }, "express": { "cookie": "0.5.0" } }}Nested overrides are tracked with a special notation in the appendix. Each entry
still gets a ledger recording when it was added:
{ "pastoralist": { "appendix": { "pg-types@^4.0.1": { "dependents": { "my-app": "pg@^8.13.1 (nested override)" }, "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "source": "manual" } }, "[email protected]": { "dependents": { "my-app": "express@^4.18.0 (nested override)" }, "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "source": "manual" } } } }}Keep npm overrides in the root package.json. Nested overrides scope a
transitive dependency to a parent; workspace manifests supply dependency
context through depPaths. npm ignores overrides declared inside workspace
packages.
Pastoralist detects and tracks patches created by tools such as patch-package.
When you have patches in your patches/ directory:
patches/├── lodash+4.17.21.patch├── express+4.18.0.patch└── react+18.2.0.patchPastoralist tracks them in the appendix:
{ "pastoralist": { "appendix": { "[email protected]": { "dependents": { "my-app": "lodash@^4.17.0" }, "patches": ["patches/lodash+4.17.21.patch"], "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "source": "manual" } } } }}Pastoralist reports potentially unused patch paths. Review those files when dependencies change; Pastoralist does not delete patches.
Pastoralist considers peerDependencies when tracking override usage.
{ "peerDependencies": { "react": "^17.0.0 || ^18.0.0" }, "overrides": { "react": "18.2.0" }}The appendix will reflect peer dependency requirements:
{ "pastoralist": { "appendix": { "[email protected]": { "dependents": { "my-component": "react@^17.0.0 || ^18.0.0" }, "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "source": "manual" } } } }}Pastoralist identifies overrides that are no longer needed and can remove them when you explicitly opt in.
--remove-unusedIn this fixture, express has already been removed and no package needs
qs. Cleanup removes the override and its tracking entry:
--- package.json+++ package.json@@ -1,18 +1,4 @@ { "name": "shepherd-cli",- "overrides": {- "qs": "6.11.2"- },- "pastoralist": {- "appendix": {- "[email protected]": {- "dependents": {- "shepherd-cli": "qs (required by express)"- },- "ledger": {- "addedDate": "2026-10-16"- }- }- }- }+ "overrides": {} }Preview removal with pastoralist --remove-unused --dry-run, then apply it
with pastoralist --remove-unused. Active ledger.keep constraints protect
entries from removal.
When an override exists but no package in your project depends on it,
Pastoralist labels it as (unused override) in the appendix:
{ "pastoralist": { "appendix": { "[email protected]": { "dependents": { "root": "stale-pkg (unused override)" } } } }}Preview removal with --remove-unused --dry-run, then apply it:
pastoralist --remove-unusedThis removes both the override from overrides and its entry from the appendix.
Set keep: true on a ledger entry to prevent --remove-unused from removing
it:
{ "[email protected]": { "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "keep": true } }}To keep an override until a date or version is reached, use a KeepConstraint:
{ "[email protected]": { "ledger": { "addedDate": "2026-05-30T00:00:00.000Z", "keep": { "reason": "Waiting for upstream patch", "untilVersion": "4.18.0", "until": "2027-06-01" } } }}Once the condition is met, --remove-unused can treat the override as removable
again.
Pastoralist tracks overrides needed by transitive dependencies:
{ "pastoralist": { "appendix": { "[email protected]": { "dependents": { "mkdirp": "minimist@^1.2.6", "optimist": "minimist@~1.2.0" } } } }}A version range that includes an override does not prove the override is redundant. Pastoralist checks dependency usage before removal and skips entries when usage cannot be established. Use ledger reasons and keep constraints for decisions that require human review.
Pastoralist keeps appendix entries while an override is still tracked. When you
run with --remove-unused, it removes both the override and the matching
appendix entry.
--remove-unused removes the override and appendix entryUse ledger reason to explain why an override is needed and keep to control
when it can be removed.
Pastoralist reads the override field your package manager already uses:
overridespnpm.overrides, or pnpm-workspace.yaml for pnpm 11+resolutionsWhen it writes changes, it preserves the existing override field when one is present. If a security fix creates the first override field in a project, Pastoralist chooses the field that matches the detected package manager.
Yarn resolutions:
{ "resolutions": { "package-a": "1.0.0", "**/package-b": "2.0.0" }}The equivalent npm or Bun override shape:
{ "overrides": { "package-a": "1.0.0", "package-b": "2.0.0" }}Use pastoralist --debug for dependency paths, config discovery, and removal
diagnostics.
Pastoralist tracks which overrides have patches from patch-package:
# Create a patch from local changes to lodashnpx patch-package lodash # Apply existing patchesnpx patch-package # Run Pastoralist to update trackingnpx pastoralistUse with npm-check-updates to manage both regular updates and overrides:
# Update dependenciesnpx npm-check-updates -unpm install # Update override trackingnpx pastoralistRun Pastoralist after your update bot installs dependencies to keep the appendix current. Use the GitHub Action for scheduled maintenance PRs.
{
"dependencies": {
"pg": "^8.13.1"
},
"overrides": {
"pg": {
"pg-types": "^4.0.1"
}
}
}{
"overrides": {
"pg": {
"pg-types": "^4.0.1",
"pg-protocol": "^1.6.0"
},
"express": {
"cookie": "0.5.0"
}
}
}{
"pastoralist": {
"appendix": {
"pg-types@^4.0.1": {
"dependents": {
"my-app": "pg@^8.13.1 (nested override)"
},
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"source": "manual"
}
},
"[email protected]": {
"dependents": {
"my-app": "express@^4.18.0 (nested override)"
},
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"source": "manual"
}
}
}
}
}patches/
├── lodash+4.17.21.patch
├── express+4.18.0.patch
└── react+18.2.0.patch{
"pastoralist": {
"appendix": {
"[email protected]": {
"dependents": {
"my-app": "lodash@^4.17.0"
},
"patches": ["patches/lodash+4.17.21.patch"],
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"source": "manual"
}
}
}
}
}{
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0"
},
"overrides": {
"react": "18.2.0"
}
}{
"pastoralist": {
"appendix": {
"[email protected]": {
"dependents": {
"my-component": "react@^17.0.0 || ^18.0.0"
},
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"source": "manual"
}
}
}
}
}--- package.json
+++ package.json
@@ -1,18 +1,4 @@
{
"name": "shepherd-cli",
- "overrides": {
- "qs": "6.11.2"
- },
- "pastoralist": {
- "appendix": {
- "[email protected]": {
- "dependents": {
- "shepherd-cli": "qs (required by express)"
- },
- "ledger": {
- "addedDate": "2026-10-16"
- }
- }
- }
- }
+ "overrides": {}
}{
"pastoralist": {
"appendix": {
"[email protected]": {
"dependents": {
"root": "stale-pkg (unused override)"
}
}
}
}
}pastoralist --remove-unused{
"[email protected]": {
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"keep": true
}
}
}{
"[email protected]": {
"ledger": {
"addedDate": "2026-05-30T00:00:00.000Z",
"keep": {
"reason": "Waiting for upstream patch",
"untilVersion": "4.18.0",
"until": "2027-06-01"
}
}
}
}{
"pastoralist": {
"appendix": {
"[email protected]": {
"dependents": {
"mkdirp": "minimist@^1.2.6",
"optimist": "minimist@~1.2.0"
}
}
}
}
}{
"resolutions": {
"package-a": "1.0.0",
"**/package-b": "2.0.0"
}
}{
"overrides": {
"package-a": "1.0.0",
"package-b": "2.0.0"
}
}# Create a patch from local changes to lodash
npx patch-package lodash
# Apply existing patches
npx patch-package
# Run Pastoralist to update tracking
npx pastoralist# Update dependencies
npx npm-check-updates -u
npm install
# Update override tracking
npx pastoralist