
Safely install NPM packages
A security-focused npm installer that protects your projects from newly compromised packages.
Supply chain attacks on npm packages are a growing threat. Attackers sometimes compromise legitimate packages by:
These attacks often happen suddenly—a package that was safe yesterday might be compromised today. safe-npm protects you by only installing package versions that have been publicly available for a minimum amount of time (90 days by default). This gives the security community time to discover and report malicious releases before they reach your project.
When you run safe-npm install, it:
package.json or command-line argumentsFor example, if you specify react@^18 and a malicious [email protected] was published yesterday, safe-npm will install the latest version that's at least 90 days old instead.
# Install globally
npm install -g @dendronhq/safe-npm
# Now you can use it anywhere
safe-npm install
# Clone and build
git clone <repository-url>
cd safe-npm
npm install
npm run build
# Link the binary globally
npm link
# Use the minimum age of 90 days (default)
safe-npm install
# Or specify your own minimum age
safe-npm install --min-age-days 120
# Install packages directly with version constraints
safe-npm install react@^18 lodash@^4.17.0
# These will be filtered to only use versions at least 90 days old
safe-npm install express --min-age-days 60
# Preview which versions would be installed without actually installing
safe-npm install --dry-run
--min-age-days <n>Default: 90
The minimum number of days a package version must have been published before it can be installed.
Example: --min-age-days 120 requires packages to be at least 4 months old.
When to adjust:
--ignore <pkg1,pkg2>A comma-separated list of packages that bypass the age requirement. These packages will still respect semver ranges but ignore the minimum age.
Example: --ignore typescript,@types/node
When to use:
--strictExit with an error if ANY dependency cannot be resolved to a version meeting the age requirement.
Example: safe-npm install --strict
When to use:
--dev / --prod-onlyControl which dependencies from package.json are processed.
Examples:
safe-npm install --dev - Only install devDependenciessafe-npm install --prod-only - Only install production dependenciesWhen to use:
--strategy <direct|overrides>Default: direct
How safe-npm installs the resolved versions:
direct - Directly installs the resolved versions using npm install package@version
overrides - Writes resolved versions to package.json overrides field, then runs npm install
--registry <url>Default: https://registry.npmjs.org
Specify an alternate npm registry.
Example: --registry https://registry.company.com
When to use:
--dry-runShow what would be installed without making any changes.
Example: safe-npm install --dry-run
When to use:
# Create a new project
mkdir my-project && cd my-project
npm init -y
# Install dependencies safely
safe-npm install express@^4 lodash
# This creates package-lock.json with versions at least 90 days old
# Check what versions would be installed with age requirements
safe-npm install --dry-run
# If you're happy, install them
safe-npm install
# In your CI pipeline, fail the build if any package can't meet age requirements
safe-npm install --strict --min-age-days 120
# Or allow newer packages for dev dependencies only
safe-npm install --prod-only --strict
# Need to urgently update a specific package? Add it to ignore list
safe-npm install --ignore package-with-critical-fix
The project includes a test suite that you can run:
npm test
For automated testing, you can mock registry responses using fixtures:
export SAFE_NPM_FIXTURES=/path/to/fixtures.json
safe-npm install
The fixtures file should contain JSON that mirrors npm registry responses for each package.
Real-world scenario:
popular-lib is maintained by a trusted developer[email protected] with malware^5.0.0 would immediately install the malicious version4.9.0 (the latest version from 90+ days ago)Security is about trade-offs. safe-npm trades bleeding-edge updates for protection against sudden supply chain compromises. It's one layer in a defense-in-depth strategy that should also include:
npm audit)ISC