npm, the package manager that ships JavaScript to millions of developers every day, has just made its most consequential security decision in years. With the release of npm 12 in August 2026, install scripts no longer run by default, and the npm registry is shifting toward a model of explicit trust. InfoQ covered the release and its implications for the JavaScript ecosystem.
TL;DR: npm 12 ships with install scripts disabled by default, closing one of the most abused supply chain attack vectors in JavaScript. The registry simultaneously moves to a model of explicit trust, requiring maintainers and consumers to actively declare what they allow. InfoQ reported the release in August 2026.
What Changed in npm 12 and Why Does It Matter?
npm 12 changes two fundamental behaviors at once: it stops executing package install scripts automatically, and it reworks how the registry communicates trust between publishers and consumers. For roughly a decade, running npm install meant silently executing arbitrary code from every dependency in the tree that declared a lifecycle script. That contract is gone.
This matters because npm is the default entry point into the JavaScript ecosystem. When the tool that installs virtually every package changes its security posture, every project, every CI pipeline, and every organization’s build process feels it. The old model assumed packages were trustworthy until proven otherwise. The new model assumes nothing.
Why now? The industry has spent years watching supply chain incidents multiply. Every time a popular package was compromised, the postmortem circled back to the same weakness: arbitrary code executing at install time, before a human ever reviewed anything. npm’s maintainers concluded that the default had to flip.
The shift also reflects a broader philosophical change. Instead of asking users to opt out of risky behavior through configuration files most never touched, npm 12 makes safety the baseline. Risk is now something you actively request. That inversion is the story of this release.
Developers who rely on packages that genuinely need compilation steps — native addons being the classic example — will notice immediately. Their builds will fail loudly rather than succeed silently. That friction is intentional. It forces a conscious decision where none existed before.
Why Are Install Scripts Now Disabled by Default?
Install scripts were disabled because they became the single most convenient mechanism for supply chain attacks against JavaScript developers. A compromised package does not need an exploit in npm itself; it only needs a postinstall hook that runs the moment someone types npm install. For years, that was enough.
The attack pattern is well documented. An attacker gains publish access to a popular package, publishes a version with a malicious lifecycle script, and waits. Every machine that installs the package executes the payload. No prompt appears. No warning is shown. The code runs with the full privileges of the user, which on developer machines often means access to tokens, SSH keys, and cloud credentials.
npm had already introduced npm ignore-scripts as an opt-in flag years earlier, and other tools in the ecosystem — pnpm and Yarn among them — offered similar mechanisms. But opt-in security rarely wins. Most developers never learned the flag existed, and tutorials continued to teach installation as a frictionless operation. The protection stayed theoretical for the majority of users.
By making the secure behavior the default, npm 12 changes the economics of these attacks. A malicious install script no longer executes on the typical machine. It only runs where a developer has explicitly granted that permission, which dramatically shrinks the blast radius of any single compromised package.
There is a real cost, and npm’s team acknowledged it. Packages with legitimate build requirements break until their consumers opt in. The trade-off is deliberate: a broken build is visible and fixable, while a silent code execution is neither. Security defaults that fail loudly beat defaults that fail invisibly.
How Does the New Explicit Trust Model for the Registry Work?
The explicit trust model flips the registry’s long-standing assumption that published packages are safe to consume without declaration. Under the new approach, trust becomes an active, visible act rather than a passive default. Maintainers must declare what their packages intend to do, and consumers must declare what they are willing to allow.
In practice, this means the registry surfaces information about package behavior — including whether a package uses install scripts — so that decisions can be made before installation, not after execution. The burden of verification moves from an implicit “npm will handle it” to an explicit statement recorded in configuration. Consumers can scope these permissions narrowly, allowing scripts only for specific packages they have reviewed rather than granting blanket execution rights.
This mirrors a wider movement in package management. Other ecosystems have been tightening their defaults around lifecycle code for years, treating postinstall execution as a privileged operation rather than an ordinary feature. npm’s move brings JavaScript in line with that trend, and InfoQ’s reporting places the change in the context of repeated supply chain incidents that eroded confidence in the implicit trust model.
The registry side matters as much as the client side. A package manager can harden its own defaults, but if the registry continues to present every package as equally trustworthy, users still lack the information needed to make good decisions. Explicit trust closes that gap by making intent and permission first-class data — visible in metadata, auditable in configuration files, and enforceable by tooling.
For organizations, this creates an enforceable policy boundary. Security teams can require that only vetted packages carry script permissions, and CI systems can fail builds that request undeclared execution. Trust becomes something you can grep for.
How Do Package Authors Opt Back Into Running Install Scripts?
Package authors opt back in by explicitly declaring their scripts and, where required, publishing the necessary metadata so consumers can make informed choices about granting permission. The mechanism replaces silent execution with a declared, reviewable contract between the package and whoever installs it.
For authors of packages with native components, the practical path is straightforward. The install and postinstall lifecycle hooks remain available; what changed is that they no longer fire without consent. Authors should document prominently that their package requires script execution, explain exactly what the script does, and ensure the code involved is minimal and inspectable. A compile step that builds a native addon is a legitimate use. A script that phones home or fetches remote payloads is exactly what this model exists to expose.
Consumers, meanwhile, grant permission through npm’s configuration system. Permissions can be scoped per package, which means a team can allow scripts for a handful of well-understood dependencies while keeping the default denial for everything else. This granularity is the point: rather than a global on/off switch, the model supports a spectrum of trust that matches actual knowledge.
The transition will not be instant. Popular packages with install-time requirements will need to update their documentation, and build pipelines will need new configuration entries. InfoQ’s coverage notes that the ecosystem response — how quickly major packages adapt their install flows — will determine how smooth the migration feels for everyday developers.
What Supply Chain Attacks Prompted This Security Shift?
Install scripts running by default were the single most abused mechanism in the npm ecosystem’s worst security incidents, and npm 12 finally removes that default. As InfoQ reports, the npm team’s decision to turn scripts off by default and move the registry toward explicit trust is a direct response to years of supply chain attacks that exploited the implicit trust developers granted to any package they installed. For most of npm’s history, running npm install meant executing arbitrary code from every dependency’s postinstall hook. That was the problem.
The pattern repeated across incident after incident. An attacker publishes a package, or compromises an existing maintainer account, and the postinstall script fires on thousands — sometimes millions — of developer machines and CI runners the moment someone types npm install. Because the script runs with the full permissions of the user, it can read environment variables, exfiltrate credentials, plant persistence mechanisms, or pivot into internal networks. No sandbox. No prompt. Just code execution by default.
Why did it take so long to change? Because install scripts are how many legitimate packages work. Native modules need to compile. CLIs want to set up platform-specific binaries. Tools like ESLint, Husky, and countless native addons depend on lifecycle hooks to function correctly. Turning scripts off by default breaks things — and that trade-off is exactly what npm 12 asks the ecosystem to accept in exchange for a dramatically smaller attack surface.
The explicit trust component addresses the other half of the problem. The old registry model treated every published package as trustworthy until proven otherwise. Explicit trust flips that assumption: publishers and packages must earn trust before their code — especially their scripts — runs anywhere.
What Breaks for Developers and CI Pipelines After Upgrading?
Packages that rely on postinstall, preinstall, or install lifecycle scripts will simply not finish setting themselves up after upgrading to npm 12, and that is the first thing teams will notice. InfoQ’s coverage makes clear this is the intended behavior, not a bug: scripts are blocked unless explicitly allowed. Native modules that compile at install time, tools that download platform binaries, git hooks managers, and packages that patch other dependencies will appear to install successfully while remaining non-functional.
The typical failure looks confusing at first. npm install exits cleanly. No error, no warning that stands out. Then the tool fails at runtime with a missing binary, a compilation that never happened, or a hook that was never registered. In CI pipelines this can surface as flaky or mysterious breakage that points nowhere near the actual cause — the skipped lifecycle script three dependencies deep in the tree.
Teams should expect friction in these areas:
- Native addons requiring node-gyp compilation triggered by
installhooks - Binary distribution packages that fetch prebuilt executables during
postinstall - Git hook managers such as Husky-style tools that wire hooks into
.git/hooks - Platform-specific packages using scripts to select the right optional variant
- Packages that patch or shim other modules after installation
- Monorepo tooling that bootstraps workspaces via lifecycle hooks
- Docker builds where a silent script skip produces a broken image layer
- Cached CI environments where the breakage only appears after a cold install
The migration path, per InfoQ’s reporting, is deliberate opt-in. Developers and pipeline maintainers can explicitly allow scripts for trusted dependencies rather than reverting to the old blanket behavior. That means auditing which packages in your lockfile actually need lifecycle scripts, allowing exactly those, and letting everything else install inert. It is more work upfront. It is also the point.
A practical rollout order for CI: upgrade one non-critical pipeline first, run a full cold install, compare the resulting node_modules against a known-good build, and only then promote the change. Teams with large dependency trees should budget real time for the audit — the packages that need scripts are rarely the ones you expect.
How Does npm 12 Compare to Alternative Approaches Like pnpm and Deno?
npm is catching up to a direction other ecosystems set years ago, and InfoQ frames npm 12 as the mainstream registry finally adopting posture that alternative tools already pioneered. pnpm, for instance, has long offered ways to control lifecycle script execution, letting users deny scripts by default and approve them selectively — the same model npm 12 now brings to the default registry client. The difference is scale: npm’s decision changes the baseline behavior for the majority of JavaScript developers, not just a self-selected security-conscious minority.
Deno took an even more radical route by designing its permission model around explicit consent from the start. Nothing runs without the runtime asking — file access, network, subprocess execution all require grants. That philosophy, applied to package installation, is conceptually identical to what explicit trust in the registry achieves: code does not execute because it exists; it executes because someone decided it should.
The comparison in practice:
| Aspect | npm 12 | pnpm | Deno |
|---|---|---|---|
| Install scripts | Off by default, opt-in per package | Deniable via config, selective approval | Designed out of the dependency model |
| Trust model | Explicit trust in registry | User-managed allowlists | Runtime permission prompts |
| Migration cost | High — ecosystem-wide default change | Low — opt-in feature already available | Highest — different runtime entirely |
| Ecosystem reach | Largest, sets new baseline | Growing minority | Niche relative to npm |
What makes npm 12 significant is not technical novelty. It is that the default moved. When pnpm users denied scripts, that was a personal hardening choice. When npm blocks scripts for everyone, package authors are forced to design packages that work without them — or to clearly communicate why scripts are needed so users can make an informed opt-in decision.
The likely long-term convergence: lifecycle scripts become a flagged, reviewed, exceptional mechanism across all major JavaScript tooling rather than an ambient expectation. npm 12 is the tipping point for that transition.
What Should Maintainers Do to Prepare Their Packages for npm 12?
Maintainers should assume their lifecycle scripts will not run for most users and redesign accordingly — that is the core preparation task. InfoQ’s reporting on npm 12 indicates the ecosystem shift is toward packages that either work without scripts entirely or make their script requirements explicit and discoverable. The packages that survive this transition cleanly are the ones that treat scripts as an optional accelerator, not a requirement.
The highest-impact move is eliminating postinstall where possible. For binary distribution, the optionalDependencies pattern — shipping platform-specific packages as real dependencies that npm resolves natively — removes the need for a script that downloads the right executable. For compilation, moving builds to prepack or publishing prebuilt artifacts means consumers never compile anything. Neither approach is new. Both now matter much more.
A preparation checklist for maintainers:
- Audit every lifecycle script in your package and document what each one actually does
- Replace download-based binary setup with platform-specific optional dependencies
- Move compilation to your publish pipeline instead of the consumer’s install step
- Test your package with scripts disabled to see exactly what breaks
- Add clear documentation telling users how to opt in if a script is genuinely required
- Publish a
READMEsection on install behavior so the opt-in decision is informed - Tag releases so users on npm 12 can pin a known-compatible version
- Watch your issue tracker for reports that start with “installed fine but doesn’t run”
Communication is half the battle. A package that needs a script should say so loudly — in the README, in release notes, and ideally in the error message users see when the tool fails without it. Silent breakage generates bug reports; documented requirements generate informed decisions.
Maintainers of widely used native modules carry the heaviest load, since compilation-on-install has been their standard model. For them, prebuilt binaries distributed as optional dependencies are the established escape hatch, and npm 12 makes investing in that infrastructure effectively mandatory.
Is npm 12 the End of Postinstall Scripts in the JavaScript Ecosystem?
No — but it is the end of postinstall scripts as an invisible default, which may amount to the same thing over time. npm 12 does not remove lifecycle scripts from the platform; it removes the assumption that they run. As InfoQ reports, the mechanism remains available through explicit opt-in. What changes is the burden of proof: a script now needs a reason to execute rather than a reason not to.
The realistic trajectory has precedents elsewhere in the ecosystem. When registries added integrity hashes, when two-factor authentication arrived for publishing, when provenance attestation became available — none of these broke existing workflows overnight. Each shifted the default until the old insecure pattern became conspicuous. Install scripts are following the same curve. Expect a period where popular packages that depend on scripts publish prominent opt-in instructions, followed by a longer period where maintainers rewrite their packages to avoid scripts altogether, because a package that installs cleanly under npm 12’s defaults is simply easier to adopt.
There will be survivors. Some legitimate use cases — native compilation on exotic platforms, licensed binary distribution, deep git-hook integration — genuinely need lifecycle execution and will persist as explicitly trusted exceptions. The ecosystem is not losing the capability. It is losing the ambient, unexamined use of it.
The more interesting question is what explicit trust does to the registry itself. If trust becomes a visible, grantable property, then package reputation stops being implicit in download counts and starts being an explicit signal consumers can evaluate. That is a slower change than the script default, but potentially a deeper one — and it is the part of npm 12 that will still be shaping the ecosystem years from now.
Frequently Asked Questions
Do I need to change my package.json to keep working with npm 12?
In most cases, no — the script-blocking change affects how npm executes lifecycle hooks, not the package manifest format itself. However, if your package relies on postinstall or similar scripts to function, you will need to either document the opt-in process for users or restructure the package to work without scripts, for example by using platform-specific optional dependencies instead of a download step. InfoQ’s coverage positions this redesign, not manifest changes, as the main migration work.
Will disabling install scripts break native modules like node-gyp builds?
Yes — native modules that trigger compilation through install or postinstall hooks will not build when scripts are blocked, which is why InfoQ highlights native compilation as the most affected category. The module will install without errors but remain non-functional until the user explicitly allows its scripts. The established workaround is distributing prebuilt binaries as platform-specific optional dependencies, which npm resolves without executing any lifecycle code.
How does explicit trust differ from the previous registry trust model?
Under the previous model, every published package was implicitly trusted: installing it meant running its code, including lifecycle scripts, without any separate consent step. Explicit trust inverts that assumption — as InfoQ reports, the registry moves to a model where trust must be granted before package code, particularly install scripts, executes on a user’s machine. The practical effect is that npm install stops being a mechanism for silent arbitrary code execution by unknown parties.
When should teams upgrade to npm 12?
Teams should upgrade once they have audited which dependencies in their lockfile depend on lifecycle scripts, since those packages will need explicit opt-in to keep functioning after the upgrade. InfoQ’s reporting indicates npm designed the transition around deliberate, per-package approval rather than a blanket revert, so the upgrade itself is safe — the breakage risk comes from unexamined script dependencies, especially in CI pipelines performing cold installs. A staged rollout on a non-critical pipeline first is the sensible approach.
Summary
npm 12 marks the moment the JavaScript ecosystem’s largest package manager stopped treating arbitrary code execution as an acceptable install-time default. The key takeaways:
- Install scripts are off by default. Lifecycle hooks like
postinstallno longer run unless explicitly allowed, closing the most commonly abused supply chain attack vector in npm’s history. - The registry moves to explicit trust. Packages must earn execution rather than receiving it implicitly, flipping an assumption that has governed npm since its inception.
- Native modules and script-dependent tools break silently. Packages relying on node-gyp builds or binary downloads install cleanly but fail at runtime until scripts are approved or the package is redesigned.
- Maintainers should eliminate scripts where possible. Platform-specific optional dependencies and prebuilt binaries are the established replacements for install-time setup.
- The change follows, and mainstreams, prior art. pnpm and Deno pioneered selective script denial and permission-based execution; npm 12 brings that posture to the default experience of most JavaScript developers.
If you maintain a package with lifecycle scripts, start testing it against npm 12’s defaults today — the packages that adapt first will be the ones users can install without a second thought. And if you consume packages, read InfoQ’s full coverage for the details on the explicit trust rollout before upgrading your production pipelines.