Safeguard
Developer Tools•

Check what goes in your npm package before you publish

Use the files field, npmignore rules and a dry run to see exactly which files ship in your npm tarball, so secrets and test data never reach the registry.

Safeguard Security Team
3 min read

Before you run npm publish, build the tarball locally and read its contents. Set an allowlist with the files field in package.json, know which files npm always includes or drops, and use npm pack or a dry run to confirm. Registries keep what you upload, so the check is cheap insurance.

How npm decides what ships

If files is omitted, npm defaults to ["*"], which means everything not ignored. That default is how test fixtures, .env copies and build scratch files end up in public packages.

The npm docs list what is always included regardless of settings: package.json, the README, the LICENSE, the file named in main, and the files named in bin. Some things are ignored by default, including .git, .npmrc, node_modules and lock files such as package-lock.json. A few of these cannot be forced in even through files: .git, .npmrc, node_modules, package-lock.json, pnpm-lock.yaml and yarn.lock. To ship a lock file, use npm-shrinkwrap.json instead.

Prefer an allowlist

Listing what to include is safer than listing what to exclude, because new files are left out until you add them:

{
  "files": ["dist/", "bin/"]
}

Patterns work like gitignore but reversed. If you rely on .npmignore instead, note two rules from the docs. A root level .npmignore does not override files, while one in a subdirectory does. And if no .npmignore exists, npm falls back to your .gitignore. That fallback surprises people who keep generated output out of git but want it in the package, and the reverse as well.

Look before you publish

Run npm pack in the package folder. It writes name-version.tgz to the current directory, and you can list its contents with tar -tzf. The npm docs also describe a --dry-run flag for pack and publish that makes no changes and reports what would happen. The docs do not say that it prints the file list, so verify its output on your npm version rather than assuming. Opening the tarball is the unambiguous check.

Things to look for:

  • anything starting with a dot, such as .env or editor folders,
  • source maps or fixtures you did not mean to share,
  • unexpected size,
  • a missing dist folder, which is the opposite mistake and breaks installs.

Make it a gate

Put the tarball listing in CI and fail when a file outside an approved pattern appears. It pairs well with the rest of a release security checklist. If an unwanted file does get out, treat any credential in it as exposed and rotate it, since removing a version does not undo copies already downloaded.

Safeguard's dependency scanning covers what you consume. The same habit applies to what you ship, so inspect it yourself.

Quick check

Does .npmignore override the files field?

At the package root it does not. In subdirectories it does, according to the npm docs.

Which files can never be published through the files field?

.git, .npmrc, node_modules, package-lock.json, pnpm-lock.yaml and yarn.lock.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.