A security-focused NPM installer that protects your projects from new compromised packages.
Supply chain attacks on NPM packages are a growing threat. Attackers sometimes compromise legitimate packages:
- stealing maintainer credentials
- Publishing malicious updates to popular packages
- Taking possession of abandoned packages
These attacks often occur suddenly—a package that was secure yesterday may be compromised today. secure-npm Protects you by only installing package versions that are publicly available for a minimum period 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 installit:
- Reads your dependencies from
package.jsonor command-line arguments - Query the npm registry to find all available versions
- Filters editions published more recently than your minimum age limit
- Selects the latest version that meets both your semester requirements and age requirements
- Installs secure version using npm
For example, if you specify react@^18 and a malicious react@18.5.0 Published yesterday, secure-npm will instead install the latest version that is at least 90 days old.
Install from npm (recommended)
# 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
Install dependencies from package.json
# 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 specific packages
# 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
Do a dry run to see what will be installed
# Preview which versions would be installed without actually installing
safe-npm install --dry-run
default: 90
The minimum number of days a package version must be published before it can be installed.
Example: --min-age-days 120 The package must be at least 4 months old.
When to adjust:
- Increase for maximum protection (e.g., 180 days for critical production systems)
- Do less and accept a little more risk if you need new features (for example, 30 days)
Comma-separated list of packages that bypass the age requirement. These packages will still respect the semester ranges but will ignore the minimum age.
Example: --ignore typescript,@types/node
When to use:
- Fast-moving packages you rely on (like TypeScript or build tools)
- Internal packages from your organization
- Packages where you urgently need the latest features
Exit with an error if a dependency cannot be resolved to a version that meets the age requirement.
Example: safe-npm install --strict
When to use:
- CI/CD pipeline where you want builds to fail instead of skipping problematic packages
- Production deployment where you need certainty
Control which dependencies are package.json are processed.
Example:
safe-npm install --dev– Install only devdependenciessafe-npm install --prod-only– Install only production dependencies
When to use:
- Setting up development tools with strict requirements
- Production builds where you want different age policies for development vs. product dependencies
default: direct
How secure-npm installs resolved versions:
direct – Installs directly using resolved versions npm install package@version
- simple and straightforward
- Good for one-time installation or script
overrides – writes resolved versions package.json Overrides the field, then runs npm install
- Applies versioning to your entire dependency tree (including variable dependencies)
- Comment: This feature is currently disabled because it does not work properly yet
default: https://registry.npmjs.org
Specify an alternative npm registry.
Example: --registry https://registry.company.com
When to use:
- private npm registries
- mirror or cache
Show what will be installed without making any changes.
Example: safe-npm install --dry-run
When to use:
- Your configuration is being tested
- Understanding which versions are available
- Before making changes to production systems
# 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
Audit an existing project
# 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:
For automated testing, you can mimic registry responses using fixtures:
export SAFE_NPM_FIXTURES=/path/to/fixtures.json
safe-npm install
The fixtures file should contain JSON that reflects the npm registry responses for each package.
Real World Scenario:
- a popular package
popular-libMaintained by a trusted developer - Attacker compromises maintainer’s npm credentials
- the attacker publishes
popular-lib@5.0.0with malware - using projects
^5.0.0will immediately install the malicious version - With secure-npm, you will continue to use
4.9.0(Latest version 90+ days ago) - Security researchers discover and report the compromise
- Malicious version is unreleased
- You have never installed a compromised version
- Will not protect against packages that were malicious from the beginning
- Delays access to legitimate new features and bug fixes
- Requires confidence that older versions do not contain undiscovered vulnerabilities
- Age-based filtering is a guess, not a guarantee
Security is about trade-offs. Safe-NPM trades state-of-the-art updates for protection from unexpected supply chain compromises. This is a layer in depth defense strategy that should also include:
- Regular security audits (
npm audit, - Review dependencies before adding new packages
- monitoring for security advice
- Using lock files to ensure reproducible builds
- Running in a sandboxed or containerized environment
- Node.js 18 or higher
- npm (for implicit installation)
isc
<a href