npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pastoralist

v1.13.6

Published

Audit, secure, and clean up package manager overrides for npm, pnpm, Yarn, and Bun.

Readme

Pastoralist

Socket Badge npm version npm downloads CI OpenSSF Scorecard codecov

Pastoralist tracks your dependency overrides: why they're there, which packages need them, and when you can remove them.

Overrides usually start as real fixes: a CVE patch, a compatibility pin, a fork, or a transitive dependency workaround.

Months later, the reason may not be clear. Was it a security fix? A transitive bug? Which packages still need it? Can it be removed? With Pastoralist, the override sets the version, and the appendix holds the context.

Use Pastoralist to document dependency overrides, remove the ones you no longer need, and track override security fixes.


Quick Start

Install the global CLI with npm:

npm install --global pastoralist

Or install the global CLI with Homebrew:

brew install yowainwright/tap/pastoralist

That's basically it. You can now run pastoralist from your shell when you manage overrides.


For local projects where you just use pastoralist within scripts or CI, npm install pastoralist --save-dev is enough. Use Homebrew when you want a global CLI outside a project install.


Try It

To see what Pastoralist will find, start with a read-only check:

pastoralist doctor

For first-run guidance across local use, agents, and CI:

pastoralist onboard

The onboarding output includes quick scripts and copy/paste prompts for agents. See the Onboarding guide for the same checklist in the docs.


Working With Your Agent

Pastoralist does not need AI to work. It is ordinary CLI software.

If you use an agent, the included skill gives it the project instructions it needs to set up Pastoralist and keep override or CVE context current later.

Set up the Pastoralist agent skill in a repo:

pastoralist --init agent-skill

Add Pastoralist to a Project

When you are ready to add Pastoralist to the project:

npm install pastoralist --save-dev
npx pastoralist

This keeps the override where your package manager expects it, explains why it exists, and leaves the installed version visible in the lockfile after install:

--- package.json
+++ package.json
@@
 {
   "name": "shepherd-cli",
   "version": "1.0.0",
   "dependencies": {
     "barn-yard": "^1.8.0"
   },
   "overrides": {
     "barn-yard": "2.0.0"
-  }
+  },
+  "pastoralist": {
+    "appendix": {
+      "[email protected]": {
+        "dependents": {
+          "shepherd-cli": "barn-yard@^1.8.0"
+        },
+        "ledger": {
+          "addedDate": "2026-08-22T00:00:00.000Z"
+        }
+      }
+    }
+  }
}

--- package-lock.json
+++ package-lock.json
@@ after npm install
-    "node_modules/barn-yard": { "version": "1.8.0" }
+    "node_modules/barn-yard": { "version": "2.0.0" }

Use npx pastoralist init when you want the config wizard for workspace paths, external config, or security scanning.

Optionally keep the appendix current after installs:

 {
  "scripts": {
+    "postinstall": "pastoralist"
  }
 }

Pastoralist can even add the hook above for you:

npx pastoralist --setup-hook

What Pastoralist Does

Track Overrides Across Package Managers

Pastoralist works with npm and Bun overrides, pnpm pnpm.overrides, and Yarn resolutions. It can also tie security fixes, patch files, workspace packages, and CI checks to the same record.

{
  // npm and Bun
  "overrides": { "barn-yard": "2.0.0" },
  // pnpm
  "pnpm": { "overrides": { "old-goat": "4.1.0" } },
  // Yarn
  "resolutions": { "escaped-sheep": "1.0.1" },
}

Record Why an Override Exists

The appendix shows why the override was added, why it is needed, or if it can be removed.

 {
  "pastoralist": {
    "appendix": {
+      "[email protected]": {
+        "dependents": { "shepherd-cli": "barn-yard@^1" },
+        "ledger": {
+          "addedDate": "2026-08-22T00:00:00.000Z",
+          "reason": "Keep the gate API compatible.",
+        },
+      },
    },
  },
 }

Keep Security Context With the Override

Security records include the advisory, severity, provider, and patched version.

 {
  "pastoralist": {
    "appendix": {
+      "[email protected]": {
+        "ledger": {
+          "addedDate": "2026-08-22T00:00:00.000Z",
+          "cves": ["CVE-escaped-sheep"],
+          "severity": "high",
+          "securityProvider": "osv",
+          "patchedVersion": "1.0.1",
+        },
+      },
    },
  },
 }

Link Local Patches

Pastoralist records the patch-package files that support an override.

 {
  "pastoralist": {
    "appendix": {
      "[email protected]": {
+        "patches": ["patches/patchy-alpaca+1.4.0.patch"],
      },
    },
  },
 }

Remove Stale Overrides Safely

Preview unused overrides before explicitly removing them.

# first, test before removing
pastoralist --remove-unused --dry-run
# remove
pastoralist --remove-unused

Consolidate Workspace Overrides

Read workspace manifests and write one appendix in the root package.json.

 {
  "pastoralist": {
+    "depPaths": "workspace",
  },
 }

Run Pastoralist in CI

Choose preview, summary, quiet, or machine-readable output.

pastoralist --dry-run
pastoralist --summary
pastoralist --quiet --checkSecurity
pastoralist --outputFormat json

CLI API

Full reference: CLI API.

The direct commands below assume pastoralist is available from a project script, global npm install, or Homebrew install. Use npx pastoralist ... for one-off project setup.

pastoralist

Type: command

Updates the target package manifest's override appendix. It reads npm overrides, pnpm pnpm.overrides, Yarn resolutions, and Bun overrides.

pastoralist
pastoralist --dry-run

Use this after dependency changes so the appendix stays tied to the override that package managers actually read. Use --dry-run to preview the same update without writing files.

--help and --version

Type: boolean options

Prints CLI help or the installed package version.

pastoralist --help
pastoralist --version # -v

Use these to check the installed CLI surface before wiring Pastoralist into scripts or CI.

--styleguide

Type: boolean option

Opens an interactive radio menu for exploring the Pastoralist DX components without reading or changing project configuration. Use the arrow keys and Enter to choose a demo. In the prompt demo, Space toggles choices, a selects all, n selects none, and Esc cancels.

pastoralist --styleguide

pastoralist doctor

Type: command

Runs a read-only health check. Internally this enables dryRun: true and summary: true.

pastoralist doctor
pastoralist doctor --outputFormat json

Use this before setup or cleanup work to see pending appendix, cleanup, and security state without changing package.json.

In JSON mode, the important proof is small:

{
  "updated": false,
  "overrideCount": 1
}

pastoralist onboard

Type: command

Prints first-run guidance for local setup, agent setup, and GitHub Action setup.

pastoralist onboard

Use this when a human or agent needs the same first-run checklist, setup commands, and CI prompt text.

pastoralist init

Type: command

Starts the config wizard. The wizard can save config to package.json or an external config file, configure workspace paths, and set up security scanning.

pastoralist init

Stores repeatable setup choices so future runs do not depend on memory or local shell history:

 {
+  "pastoralist": {
+    "depPaths": "workspace",
+    "checkSecurity": true
+  }
 }

pastoralist init agent-skill

Type: command

Installs the bundled Pastoralist agent skill into .agents/skills/pastoralist. Existing unmanaged skill files are preserved.

pastoralist init agent-skill

Use this to give agents Pastoralist-specific setup and maintenance instructions. The marker file lets Pastoralist update only the skill files it manages.

--- .agents/skills/pastoralist/SKILL.md
+++ .agents/skills/pastoralist/SKILL.md
@@
+Use `npx pastoralist doctor` for read-only project health.
+Use `npx pastoralist --remove-unused` only after reviewing dry-run output.

--- .agents/skills/pastoralist/.pastoralist-agent-config
+++ .agents/skills/pastoralist/.pastoralist-agent-config
@@
+pastoralist-agent-config

--path, -p

Type: string option Default: "package.json"

Selects the package manifest Pastoralist should read and update.

pastoralist --path packages/app/package.json # -p packages/app/package.json

Use this when the manifest you want to check is not the root package.json.

--root, -r

Type: string option

Sets the root directory used to resolve relative paths, config files, lockfiles, patches, and workspace globs.

pastoralist --root ../my-project # -r ../my-project

Use this when scripts run outside the project directory but paths should still resolve from the project root.

--depPaths, -d

Type: string[] option

Scans additional package manifests for monorepo dependency context. Values are collected until the next flag.

pastoralist --depPaths "packages/*/package.json" # -d "packages/*/package.json"

Use this in monorepos so one root appendix can explain which packages still need each override.

For a small barn-yard workspace, it turns scattered dependents into one root ledger entry:

--- package.json
+++ package.json
@@
+  "pastoralist": {
+    "appendix": {
+      "[email protected]": {
+        "dependents": {
+          "shepherd-cli": "barn-yard@^1.8.0",
+          "pasture-ui": "barn-yard@^1.9.0"
+        }
+      }
+    }
+  }

--ignore

Type: string[] option

Excludes package manifests from --depPaths matching.

pastoralist --ignore "**/node_modules/**"

Use this to keep generated, vendored, or irrelevant manifests out of workspace scans.

--debug

Type: boolean option

Enables debug logging for CLI execution.

pastoralist --debug

Use this when config discovery, workspace matching, or provider behavior needs a trace.

--dry-run

Type: boolean option

Previews package, appendix, override-source, and security changes without writing files.

pastoralist --dry-run

Use this before committing config, appendix, cleanup, or security changes.

--outputFormat

Type: "text" | "json" option Default: "text"

Selects terminal output or a single machine-readable JSON result.

pastoralist --dry-run --outputFormat json

Use JSON output when CI or another tool needs stable fields instead of terminal text. See PastoralistResult below for the full shape.

{
  "success": true,
  "updated": false,
  "overrideCount": 1
}

--summary

Type: boolean option

Prints the metrics table after a text-mode run.

pastoralist --summary

Use this for human-readable run metrics without switching to JSON output.

--quiet, -q

Type: boolean option

Suppresses normal text output for CI. Security findings make the command exit with code 1; clean security checks exit with code 0.

pastoralist --quiet --checkSecurity # -q --checkSecurity

Use this when CI should fail on vulnerabilities without printing the normal terminal report.

--setup-hook

Type: boolean option

Adds pastoralist to the target manifest's postinstall script. Existing postinstall scripts are appended with && pastoralist.

pastoralist --setup-hook

Keeps the appendix current after package installs:

 {
   "scripts": {
-    "postinstall": "build"
+    "postinstall": "build && pastoralist"
   }
 }

--remove-unused

Type: boolean option

Removes verified unused override entries from the active override source and appendix. Preview first with --dry-run.

pastoralist --remove-unused

Removes stale override records only after verification says they are no longer needed:

--- package.json
+++ package.json
@@
 {
   "overrides": {
-    "stray-sheep": "1.0.0"
   },
   "pastoralist": {
     "appendix": {
-      "[email protected]": {}
     }
   }
 }

--- package-lock.json
+++ package-lock.json
@@ after npm install
-    "node_modules/stray-sheep": { "version": "1.0.0" }

--checkSecurity

Type: boolean option

Runs vulnerability scanning before the appendix update. Fixable security findings can add override data and security ledger fields.

pastoralist --checkSecurity

Use this to connect vulnerability evidence to the override. With --forceSecurityRefactor or an approved --interactive fix, Pastoralist can add the patched override and security ledger fields:

--- package.json
+++ package.json
@@
 {
+  "overrides": {
+    "barn-yard": "2.0.0"
+  },
+  "pastoralist": {
+    "appendix": {
+      "[email protected]": {
+        "ledger": {
+          "source": "security",
+          "cves": ["CVE-barn-yard-gate"],
+          "patchedVersion": "2.0.0"
+        }
+      }
+    }
+  }
 }

--- package-lock.json
+++ package-lock.json
@@ after npm install
-    "node_modules/barn-yard": { "version": "1.8.0" }
+    "node_modules/barn-yard": { "version": "2.0.0" }

--securityProvider

Type: "osv" | "github" | "snyk" | "npm" | "socket" | "spektion" | string[] option

Chooses one or more security providers. OSV is the default when security is enabled and no provider is set.

pastoralist --checkSecurity --securityProvider osv

Use this when you need a specific advisory source. OSV is the default when security is enabled and no provider is set.

--securityProviderToken

Type: string option

Passes a provider token for a single run. Prefer provider environment variables for CI: GITHUB_TOKEN, SNYK_TOKEN, SOCKET_SECURITY_API_KEY, or SPEKTION_API_KEY.

pastoralist --checkSecurity --securityProvider github --securityProviderToken "$GITHUB_TOKEN"

Use this for a one-off authenticated scan without writing tokens to project config.

Security Mode Flags

Type: boolean options

Controls how security findings are handled: --interactive prompts for fixes, --forceSecurityRefactor applies available fixes without prompting, --hasWorkspaceSecurityChecks includes workspace packages, --promptForReasons asks for manual ledger reasons, and --strict fails on provider errors.

pastoralist --checkSecurity --interactive
pastoralist --checkSecurity --forceSecurityRefactor --strict
pastoralist --checkSecurity --hasWorkspaceSecurityChecks
pastoralist --promptForReasons

Use --interactive for review, --forceSecurityRefactor for unattended fixes, and --strict when provider errors should fail the run.

Cache Flags

Type: string | number | boolean options

Controls provider cache behavior. --cache-dir changes the cache directory, --cache-ttl sets TTL seconds, --no-cache bypasses reads and writes, and --refresh-cache bypasses reads while writing fresh data.

pastoralist --checkSecurity --cache-dir .cache/pastoralist
pastoralist --checkSecurity --cache-ttl 3600
pastoralist --checkSecurity --no-cache
pastoralist --checkSecurity --refresh-cache

Use these to avoid repeated provider calls, shorten cache windows, or force a fresh advisory lookup.

Data API

Full reference: Data API.

PastoralistResult

Type: object

The JSON output shape returned by text-independent CLI runs. It reports write status, security status, unused overrides, applied string overrides, errors, and metrics.

pastoralist --dry-run --outputFormat json
{
  "success": true,
  "hasSecurityIssues": false,
  "hasUnusedOverrides": true,
  "updated": false,
  "securityAlertCount": 0,
  "unusedOverrideCount": 1,
  "overrideCount": 2,
  "errors": [],
  "securityAlerts": [],
  "unusedOverrides": ["[email protected]"],
  "appliedOverrides": {
    "old-goat": "4.1.0"
  },
  "metrics": {
    "packagesScanned": 1,
    "workspacePackagesScanned": 0,
    "appendixEntriesUpdated": 2,
    "vulnerabilitiesBlocked": 0,
    "overridesAdded": 0,
    "overridesRemoved": 0,
    "removedOverridePackages": [],
    "severityCritical": 0,
    "severityHigh": 0,
    "severityMedium": 0,
    "severityLow": 0,
    "writeSuccess": false,
    "writeSkipped": true
  }
}

pastoralist.appendix

Type: Record<string, AppendixItem>

Stores the ledger entry for each override version. Keys use package-name@version; values can include root dependencies, dependents, patches, and ledger metadata.

{
  "pastoralist": {
    "appendix": {
      "[email protected]": {
        "dependents": {
          "shepherd-cli": "old-goat@^3.0.0"
        },
        "ledger": {
          "addedDate": "2026-08-22T00:00:00.000Z",
          "reason": "Keep the older shepherd-cli integration working."
        }
      }
    }
  }
}

AppendixItem.ledger

Type: object

Records why an override exists and the security context behind it. Security runs can add CVEs, severity, provider, patched version, source, confidence, and resolution fields.

{
  "ledger": {
    "addedDate": "2026-08-22T00:00:00.000Z",
    "source": "security",
    "securityProvider": "osv",
    "cves": ["CVE-2026-1234"],
    "severity": "high",
    "patchedVersion": "4.1.0",
    "keep": {
      "reason": "Wait for upstream compatibility confirmation.",
      "reviewBy": "2026-09-30"
    }
  }
}

Node.js API

Full reference: Node.js API.

update(options)

Type: (options: Options) => UpdateContext

Runs the core override and appendix update from JavaScript or TypeScript. Pass a parsed package manifest as config and the manifest path.

import { resolveJSON, update } from "pastoralist";

const path = "./package.json";
const config = resolveJSON(path);

if (config) {
  const result = update({
    config,
    path,
    dryRun: true,
    depPaths: ["packages/*/package.json"],
  });

  process.stdout.write(`${result.metrics?.appendixEntriesUpdated ?? 0} entries\n`);
}

SecurityChecker.checkSecurity(config, options)

Type: (config: PastoralistJSON, options?: SecurityCheckRuntimeOptions) => Promise<SecurityCheckResult>

Runs provider-backed vulnerability scanning directly and returns alerts, suggested overrides, update suggestions, package counts, and optional best-case metadata.

import { resolveJSON, SecurityChecker } from "pastoralist";

const config = resolveJSON("./package.json");
const checker = new SecurityChecker({ provider: "osv" });

if (config) {
  const result = await checker.checkSecurity(config, {
    root: process.cwd(),
    packageJsonPath: "./package.json",
    severityThreshold: "high",
  });

  process.stdout.write(`${result.alerts.length} alerts found\n`);
}

Configuration

Pastoralist reads config from package.json#pastoralist or an external config file. External config files use top-level Pastoralist settings.

Config Files

Type: ".pastoralistrc" | ".pastoralistrc.json" | "pastoralist.json" | "pastoralist.config.cjs" | "pastoralist.config.js" | "pastoralist.config.mjs"

Pastoralist searches for the first matching external config file in this order: .pastoralistrc, .pastoralistrc.json, pastoralist.json, pastoralist.config.cjs, pastoralist.config.js, then pastoralist.config.mjs. External config is merged with package.json#pastoralist; package.json wins on conflicts.

{
  "pastoralist": {
    "depPaths": "workspace",
    "checkSecurity": true
  }
}
export default {
  depPaths: ["packages/*/package.json", "apps/*/package.json"],
  checkSecurity: true,
};

$schema

Type: string

The JSON Schema is exported as pastoralist/schema.json.

External JSON config files can reference ./node_modules/pastoralist/src/schema.json with $schema. Configs that reference this schema reject unknown or mistyped fields; other configs retain compatible validation behavior.

{
  "$schema": "./node_modules/pastoralist/src/schema.json",
  "depPaths": "workspace",
  "checkSecurity": true
}

depPaths

Type: "workspace" | "workspaces" | string[]

Defines additional package manifests used for monorepo dependency context. "workspace" and "workspaces" resolve from the root manifest's workspaces field.

{
  "workspaces": ["packages/*", "apps/*"],
  "pastoralist": {
    "depPaths": "workspace"
  }
}
{
  "depPaths": ["packages/*/package.json", "apps/*/package.json"]
}

overrideSource

Type: string

Reads and writes native overrides from a separate JSON or YAML file instead of the target package manifest. For pnpm 11 projects, Pastoralist can also resolve pnpm-workspace.yaml automatically.

{
  "pastoralist": {
    "overrideSource": "config/overrides.json"
  }
}
packages:
  - packages/*
overrides:
  old-goat: 4.1.0

appendixSource

Type: string

Writes appendix data to a JSON config file instead of embedding it in package.json. The target must be JSON or .pastoralistrc.

{
  "pastoralist": {
    "appendixSource": ".pastoralistrc.json"
  }
}

compactAppendix

Type: boolean

Stores routine appendix entries as { "addedDate": "..." } when no dependency, patch, security, or keep data needs to stay expanded.

{
  "pastoralist": {
    "compactAppendix": true
  }
}

overridePaths and resolutionPaths

Type: Record<string, Appendix>

Keeps manual appendix data for packages whose overrides or resolutions live in workspace-specific paths. resolutionPaths is the Yarn-oriented fallback.

{
  "pastoralist": {
    "overridePaths": {
      "packages/web/package.json": {
        "[email protected]": {
          "ledger": {
            "addedDate": "2026-08-22T00:00:00.000Z",
            "reason": "Pinned for the web app release."
          }
        }
      }
    }
  }
}

checkSecurity

Type: boolean

Enables security scanning from config. security.enabled can override this inside the nested security config.

{
  "pastoralist": {
    "checkSecurity": true
  }
}

security

Type: object

Configures security scanning. Supported fields are enabled, provider, autoFix, interactive, securityProviderToken, severityThreshold, excludePackages, hasWorkspaceSecurityChecks, strict, and preferLatest.

{
  "pastoralist": {
    "security": {
      "enabled": true,
      "provider": ["osv", "npm"],
      "severityThreshold": "medium",
      "excludePackages": ["@types/*"],
      "hasWorkspaceSecurityChecks": true,
      "strict": true
    }
  }
}

bestCase

Type: BestCaseConfig

Opts into portfolio-level security fix selection. Pastoralist ranks complete version states by ordered objectives instead of picking each package fix in isolation.

{
  "pastoralist": {
    "checkSecurity": true,
    "bestCase": {
      "enabled": true,
      "userOwnedOverrides": ["alpha"],
      "riskAggregation": "both",
      "objectives": ["known-exploited", "critical", "high", "change-count"],
      "search": {
        "mode": "auto",
        "exactStateLimit": 256,
        "beamWidth": 16,
        "maxEvaluations": 1000
      }
    }
  }
}

See Configuration and Workspaces for the full setup surface.

GitHub Action

Check override tracking on pull requests:

 name: Override Check
 on: [pull_request]

 jobs:
  pastoralist:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
+      - uses: yowainwright/pastoralist@v1
+        with:
+          mode: check
+          check-security: false

The action can also run security checks, update files, or open scheduled maintenance PRs. See the GitHub Action docs.

Security and Release Assurance

  • Releases are published from GitHub Actions with npm provenance
  • Published tarballs are packed before release and attached to GitHub Releases with artifact attestations
  • Stable Homebrew releases build, test, and attest the binary asset matrix
  • Stable releases open a reviewed Homebrew tap update
  • CI runs CodeQL, OpenSSF Scorecard, unit, integration, e2e, and dependency policy checks

You can verify registry signatures from your project:

npm audit signatures

Please reach out with any desired security requests and I will do my best to support you!

Thanks

Shout out to Mardin for the conversation, insight, and pairing around this topic.

Made by @yowainwright. MIT, 2022-2026.