velvet-rope
v0.1.0
Published
Block installs of packages published within a configurable minimum age — a velvet rope for your dependencies
Maintainers
Readme

On May 11, 2026, an attacker published 84 malicious versions across 42 @tanstack/* packages. The window between "published" and "detected" was 20 minutes. Anyone who ran npm install in that window ran credential-harvesting malware on their machine.
Twenty minutes.
npm trusts every package the moment it's published. No cooling-off period. No waiting for the security community to notice. velvet-rope adds that wait. Inspired by the TanStack supply chain compromise postmortem.
Renovate has minimumReleaseAge, but that only gates automated PRs — it doesn't stop you from running npm install some-package manually. This does.
What it does
Wraps npm install and checks the publish date of each package against the npm registry. If any package was published within the configured minimum age, the install fails with a clear error.
velvet-rope install @tanstack/react-router
✗ @tanstack/[email protected] was published 2 days ago (minimum: 7 days)
Blocked. Use --force or set VELVET_ROPE_BYPASS=1 to override.Configuration
Add to package.json:
{
"ageGate": {
"minimumAge": "7 days"
}
}Usage
Install as a dev dependency:
npm install --save-dev velvet-ropeUse velvet-rope install instead of npm install when adding new packages:
velvet-rope install react@latest
velvet-rope install @angular/[email protected] @angular/[email protected]To audit all direct dependencies against the registry:
velvet-rope checkEscape hatch
VELVET_ROPE_BYPASS=1 velvet-rope install # CI override
velvet-rope install --force # explicit override, logs a warningBypasses are always logged. There's no silent skip.
