# npm-security-best-practices: hardening npm, pnpm, yarn and bun installs

> npm-security-best-practices is a curated, MIT licensed checklist for defending JavaScript package installs against supply chain attacks, plus ready made package manager configs and an agent skill. It ships guidance rather than a scanner, so it works as a reference layer on top of tools such as Socket and Snyk.

**bodadotsh/npm-security-best-practices** — [Updated for AI 🤖] Continuous updates on how to stay safe from NPM supply chain attacks

- Repository: https://github.com/bodadotsh/npm-security-best-practices
- Website: https://github.com/bodadotsh/npm-security-best-practices
- Stars: 858 · Forks: 20
- Language: PowerShell
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/bodadotsh-npm-security-best-practices

## A written reference, not a scanner that runs in your pipeline

The top level entries of npm-security-best-practices make the shape of the project plain: .gitignore, .markdownlint.json, .npmrc, .vscode/, .yarnrc.yml, LICENSE, README.md, bunfig.toml, default.ps1, default.sh, deno.json, lessnews.png, npm_meme.png, pnpm-workspace.yaml and skills/. There is no library export, no bin entry and no package published for consumption by an application. What you get is prose, configuration samples and a skill definition, under an MIT licence, with the primary language recorded as PowerShell.

That distinction matters when you evaluate it for an organisation. A scanner inspects one dependency tree and returns findings. This repository gives you the settings and habits that remove whole classes of exposure before a package is ever fetched: lifecycle scripts that run on install, unpinned versions that float, missing lockfiles, publish tokens with too much scope. The README describes the goal plainly, consolidating a list of information useful for securing yourself against npm supply chain incidents, and it covers npm, bun, deno, pnpm, yarn and more.

Treat it as a policy document with working examples attached, not as a tool you add to a build. If your team wants continuous detection, this is not it, and the guide itself points elsewhere for that.

## Clearing package manager caches after a compromised release

The emergency section is the most immediately actionable part of the guide, and it is written as shell commands you can run as written. The idea is that a malicious tarball may already sit in a local cache, so cleaning the project and global caches is the first mechanical step after confirming an incident.

The README gives one block that covers project level caches and one that covers the global stores:

```sh
# remove project cache
rm -rf node_modules
yarn cache clean
pnpm cache delete

# remove global cache
npm cache clean --force
yarn cache clean --mirror
bun pm cache rm
pnpm store prune
```

The commands are not interchangeable across managers, which is exactly the point of listing them together. A pnpm content addressed store is pruned with `pnpm store prune` while a yarn mirror is cleared with `yarn cache clean --mirror`, and npm needs the `--force` flag. If your project uses one manager only, run that manager's line and skip the rest.

Stray install directories elsewhere on the machine are handled separately. The guide offers `npx npkill`, with a variant that removes every directory it finds:

```sh
npx npkill --delete-all
```

and a shell fallback when you would rather not install a helper:

```sh
find . -name 'node_modules' -type d -prune -print -exec trash '{}' \;
```

The find variant trashes directories instead of deleting them, which is the safer default if you might need to inspect what was installed. The README does not document rollback for any of these steps, so treat cache removal as irreversible in practice and keep the evidence described next before running anything.

## Preserving evidence before you delete a single cache

The guide places evidence preservation ahead of cleanup, and the reasoning is concrete rather than cautionary. Before deleting caches or `node_modules`, the README asks you to preserve CI logs, package manager logs, lockfiles, `package.json`, npm token audit history and a timestamped list of installed packages. Those artefacts support root cause analysis, credential impact review, and later coordinated disclosure or insurance reporting.

That ordering is the difference between an incident you can scope and an incident you can only describe. A timestamped package list tells you exactly which versions entered the build and on what date. Token audit history tells you which npm tokens were active when the malicious version was installed. CI logs show which pipeline ran the install script.

The follow-up steps follow the same logic. Downgrade and pin dependencies to a known clean version, or remove them entirely. Disable automated pipelines or restrict them while the investigation is ongoing. Rotate all credentials: the guide names npm tokens, GitHub PATs, SSH keys and cloud provider credentials, on the grounds that supply chain attacks often target credentials held on the system. It also advises limiting outbound network access to trusted domains, limiting or revoking access from outsiders and third party tools, and resuming work on a brand new system, which it marks as highly recommended.

The credential rotation step is the one most teams under execute. An attacker who lands a malicious lifecycle script runs with the CI environment's variables, so a clean `node_modules` directory says little about what was actually read.

## Helper configs per package manager, and two scripts to apply them

The repository carries example safer default configurations for each supported manager: `.npmrc`, `bunfig.toml`, `pnpm-workspace.yaml`, `deno.json` and `.yarnrc.yml`. Alongside them sit `default.sh` and `default.ps1`, described in the README as a helper script for adding security to your local machine. The presence of a PowerShell variant next to the shell variant explains why the project records PowerShell as its primary language even though the topic is JavaScript tooling.

The division of labour is sensible. The config files are the durable state: they are what you commit, review and inherit, and each one targets the settings that its own package manager understands. npm reads `.npmrc`, bun reads `bunfig.toml`, pnpm reads `pnpm-workspace.yaml`, deno reads `deno.json` and yarn reads `.yarnrc.yml`. A project that switches managers will need to port the intent, because none of these files substitutes for another.

The two helper scripts exist because hand editing five formats is error prone, and because the people most exposed to supply chain risk are often running on Windows. Note what the README does not do here: it links the files and names the script but does not print the setting values inline, so you have to open the files to see what each one contains before applying it. That is a deliberate omission for a security document and a mild inconvenience for evaluation, since a config that is copied without being read is a config nobody can defend in review.

The guide also suggests npmx.dev over npmjs.com, calling it a modern registry browser with features like detailed package pages, comparison, and source code access.

## The agent skill is the one part you can install with a command

Most of this repository is text. One part is installable, because the project packages its guidance as an agent skill. The README points at `skills/npm-security/SKILL.md`, described as a file that guides coding agents to apply these security best practices, with lifecycle scripts off, cooldowns and exact versions named as examples of what it instructs the agent to do.

Installing it takes one command:

```sh
npx skills add bodadotsh/npm-security-best-practices
```

This is the interesting design decision in the project. Most supply chain advice assumes a human developer who will read a policy once and remember it. An agent skill moves the same checklist into the loop that writes the package.json, runs the install and sets up CI, which is exactly where lifecycle scripts, version pinning and cooldown settings get decided. The guide's description reflects the same intent, updated for AI tooling.

There is a trade-off worth naming. An agent that writes stricter configuration is useful, but the enforcement point is the machine that reads the config files, not the model. If `default.sh` never runs and `.npmrc` is never copied into the repository, an agent skill that knows about cooldown settings changes nothing on disk. Use the skill and the committed config files together, and verify the resulting files yourself.

## What the numbered sections actually ask you to change

The table of contents is effectively the policy. For developers it lists disabling lifecycle scripts, setting cooldowns or a minimum release age, including lockfiles, pinning dependency versions, preinstall preventions, runtime protections, reducing external dependencies and isolated development. For maintainers it lists enabling 2FA, creating tokens with limited access, generating provenance statements and reviewing published files. A miscellaneous group covers npm organization, alternative registries, audit, monitoring and security tools, and supporting OSS.

Read that list as a set of layers rather than a ranking. Disabling lifecycle scripts stops install time code execution. Cooldowns and a minimum release age narrow the window in which a freshly published malicious version can reach a build, because compromise is usually detected after publication. Lockfiles and exact pins make installs reproducible, so a good tree stays good. Isolated development keeps a developer's workstation away from production credentials. For maintainers the controls apply in the opposite direction, because a maintainer account is the thing an attacker wants to publish from, hence 2FA, scoped tokens, provenance statements and a review step for published files.

The difference in approach versus a scanner is worth stating plainly. Socket and Snyk, both linked from the guide, inspect dependencies and tell you what is wrong with the current tree. This checklist asks you to change defaults so fewer things are wrong with the tree in the first place. Use them for the first, use this for the second.

## Case studies read as a timeline of the ecosystem

The repository maintains a table of npm supply chain incidents with dates and links to outside write ups, which turns it into a rough history of the ecosystem rather than a static list of tips. The entries include Keyv and friends on 2026-08-04, `@tanstack/*` on 2026-05-11, axios on 2026-03-31, PostHog on 2025-11-24, CrowdStrike on 2025-09-24, debug and chalk on 2025-09-08, `@nx/*` on 2025-08-26, and tj-actions/changed-files on 2025-03-15.

Each row points at primary write ups, with Socket, StepSecurity and Aikido appearing repeatedly as sources, and several rows link a Hacker News discussion. Reading the sequence makes one thing clear about why this checklist exists at all: packages with thousands of dependents and tiny or single maintainer ownership keep turning up in these incidents, which is the argument for reducing external dependencies and for keeping registry tokens narrowly scoped.

The table is also the guide's detection advice in practice. It points at a newsfeed as the personal choice of the author and at vulnerability databases at security.snyk.io and a Socket npm search page for confirmation. So the workflow the project implies is monitor, confirm, then apply the numbered controls.

## Releases, dates and what the MIT licence does not cover

The repository is not archived, and the last push was on 2026-09-30. Releases follow a calendar style version scheme: v2026.9.24 published on 2026-09-24, v2026.6.30 on 2026-06-30 and v2026.5.29 on 2026-05-29. Three releases across the last few months, with pushes following the release dates, suggests the content is revised on a monthly cadence rather than left to rot.

The MIT licence covers the repository text and the sample configuration files. It says nothing about the third party packages and services the guide links to, and it does not make the samples a warranty that a given setting blocks a given attack. The configs are starting points that you are expected to read and adapt to your own registry usage, your CI runner and your organisation's rules. The linked write ups, the npmx.dev browser and the vulnerability databases remain under their own terms.

The upgrade cost of following this guidance is low in engineering time and low in tooling, because most of it is configuration and habit. The real cost is attention: every guideline in the numbered list is a decision your team has to keep making on every new project, and the guide gives no automated way to check that any of it is still true.

## Conclusion

Adopt npm-security-best-practices as the reference your team reads before it configures a new JavaScript project, and copy the shipped .npmrc, bunfig.toml, pnpm-workspace.yaml, deno.json and .yarnrc.yml files into a scratch directory first. Skip it if you expect automated scanning, because nothing here inspects a lockfile for you. Verify first what the helper configs actually change on your own machine, since the last push was on 2026-09-30 and the checklist itself does not state the exact setting values.

## FAQ

### How do I install npm-security-best-practices in my project?

It is a checklist repository with sample config files rather than a runtime package, so there is nothing to add to your dependencies. The one installable piece is the agent skill, added with `npx skills add bodadotsh/npm-security-best-practices`.

### Which package managers does npm-security-best-practices cover?

The guide covers npm, bun, deno, pnpm, yarn and more. It ships example safer default configurations for each one: `.npmrc`, `bunfig.toml`, `pnpm-workspace.yaml`, `deno.json` and `.yarnrc.yml`, plus a `default.sh` and `default.ps1` helper script.

### What should I do first if a dependency I use was compromised?

Preserve CI logs, package manager logs, lockfiles, `package.json`, npm token audit history and a timestamped list of installed packages before deleting caches or `node_modules`. Then clean the caches, downgrade and pin to a known clean version or remove the package, restrict automated pipelines, and rotate npm tokens, GitHub PATs, SSH keys and cloud provider credentials.

### Does npm-security-best-practices include a vulnerability scanner?

No. It contains written guidance, configuration samples and an agent skill. For scanning it points to other services, naming socket.dev and security.snyk.io, and it suggests npmx.dev as a registry browser with package details, comparison and source code access.

## Sources

- [bodadotsh/npm-security-best-practices on GitHub](https://github.com/bodadotsh/npm-security-best-practices)
- [License: MIT](https://github.com/bodadotsh/npm-security-best-practices/blob/main/LICENSE)
- [Project website](https://github.com/bodadotsh/npm-security-best-practices)
- [README](https://github.com/bodadotsh/npm-security-best-practices/blob/main/README.md)
- [Releases](https://github.com/bodadotsh/npm-security-best-practices/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bodadotsh-npm-security-best-practices
