You have reached the beginning of time!

npm v12 Blocks Install Scripts. So Why Aren't You Safe Yet?

🎙️ This article accompanies Episode 3 of Café con CVEs, our Spanish-language podcast where the NodeSource team explores software supply chain security, Node.js internals, and the real-world vulnerabilities affecting the JavaScript ecosystem.

In Episode 2 we explored one of the biggest security changes coming to npm in years: the end of automatic install scripts. This article continues that discussion by answering the question every developer eventually asks:

In Episode 2 we explored one of the biggest security changes coming to npm in years: the end of automatic install scripts. This article continues that discussion by answering the question every developer eventually asks:

If install scripts are blocked, haven't we solved the problem?

📺 Watch the full episode on YouTube: https://youtu.be/3maN0X9DXnI


When npm announced that version 12 would require developers to explicitly approve install scripts, the reaction across the community was almost universally positive. For years, security researchers had warned that package installation had become one of the weakest links in the JavaScript supply chain. Every npm install represented an opportunity for third-party code to execute automatically, often before developers had even looked at the source they were downloading. After incidents such as the compromise of chalk, debug, Shai-Hulud, and Miasma, it was difficult to argue that the existing trust model was still appropriate.

The new approval workflow changes that. Packages are no longer free to execute installation hooks simply because they happen to exist somewhere in your dependency graph. Instead, developers must explicitly decide which dependencies are allowed to perform privileged installation tasks. It's a significant shift in philosophy—from implicit trust to explicit approval—and arguably one of the most important security improvements npm has introduced in more than a decade.

It's also very easy to misunderstand what this change actually accomplishes.

Reading the announcement, some developers came away with the impression that npm had finally solved software supply chain attacks. If malicious packages can no longer execute code during installation, then surely the primary attack vector has disappeared. The reasoning sounds intuitive, but it rests on an assumption that has never really been true: that install scripts were the thing enabling arbitrary code execution.

They weren't.

Install scripts were merely one moment in which arbitrary code could run. What npm v12 removes is the trigger, not the capability itself. The ability for a package to execute JavaScript doesn't come from npm at all—it comes from the JavaScript module system. Every package you install eventually needs to be imported, and importing a module has always meant evaluating its top-level code before your application can use it. That behavior exists in CommonJS, in ECMAScript Modules, in browsers, in Node.js, in Deno, and in virtually every modern JavaScript runtime. Removing it would not be a security improvement; it would fundamentally change how the language works.

This distinction is subtle, but it changes the entire conversation around supply chain security. Once you stop thinking about installation as the problem and start thinking about execution, it becomes clear why npm alone cannot solve this class of attacks. Package managers can decide what happens while software is being downloaded. They cannot redefine how JavaScript executes once your application starts running. That responsibility belongs to the runtime, and that is exactly where the conversation moves after npm v12.


Further Reading

Incident Reports

The NodeSource platform offers a high-definition view of the performance, security and behavior of Node.js applications and functions.

Start for Free