npm v12 Breaking Changes: Migration Guide for Developers
Technical Deep-Dive · June 10, 2026

npm v12 Breaking Changes:
Prepare Your Migration Today

npm v12, estimated for July 2026, introduces three security-breaking default changes that affect every Node.js developer. Install scripts become opt-in, remote tarballs are blocked, and Git dependencies require explicit approval. Here's exactly what's changing and how to migrate.

Oleg Maximov June 10, 2026 10 min read

The Three Breaking Changes at a Glance

On June 9, 2026, the GitHub Changelog confirmed the final set of default changes shipping in npm v12. These have been available behind warnings since npm 11.10.0, but v12 flips them on by default:

Breaking

Install Scripts Opt-In by Default

preinstall, install, and postinstall scripts in dependencies will no longer run automatically. You must explicitly approve them using npm approve-scripts and npm deny-scripts. Available behind warnings in npm 11.16.0+.

Breaking

--allow-remote Defaults to None

npm will no longer resolve dependencies from remote URLs — including HTTPS tarballs — unless explicitly allowed via --allow-remote. This covers both direct and transitive dependencies. Available behind warnings in npm 11.15.0+.

Breaking

--allow-git Defaults to None

Git dependencies (direct or transitive) are blocked by default. This closes a specific code-execution path where a Git dependency's .npmrc could override the Git executable — even with --ignore-scripts. Available behind warnings in npm 11.10.0+.

All three changes can be tested right now in npm 11.10.0+. The warnings will tell you exactly which packages are affected in your project. Don't wait until July to discover your build breaks.

Why These Changes Now?

Install scripts have become the primary attack vector for npm supply chain attacks. The Mini Shai-Hulud worm (May 2026) compromised over 170 packages by injecting malicious code through preinstall hooks. Other package managers — pnpm, Yarn, Bun, Deno — either block install scripts by default or require explicit approval. npm was the only holdout.

The allow-remote and allow-git changes close additional vectors. The Git dependency issue was especially dangerous: a compromised Git dependency's .npmrc could override the Git executable npm uses to checkout repos, effectively giving an attacker control over the install process even when scripts were disabled.

For a deeper analysis of the attack landscape that led to these changes, see my npm Install Scripts Opt-In RFC analysis and the Mini Shai-Hulud supply chain attack breakdown.

Migration Step-by-Step

Step 1: Upgrade npm

First, upgrade to npm 11.16.0+ to enable all warnings:

# Upgrade to latest npm 11
npm install -g npm@11

# Verify version
npm --version
# Should be 11.16.0 or higher

# Install with warnings enabled
npm install --install-strategy=manual

Step 2: Find All Packages with Install Scripts

Run the query command to list every dependency that uses install scripts:

# List all packages with scripts
npm query .scripts

# Get a concise list of package names only
npm query .scripts | jq '.[].name'

# Check with warnings (npm 11.16+)
npm install --install-strategy=manual
# Warnings will show: "package X has 1 script(s) that will not run in v12"

Typical packages that trigger this warning include:

Step 3: Review and Approve Trusted Packages

npm 11.16+ introduces two new commands for managing the script allowlist:

# Approve a specific package's scripts
npx npm-approve-scripts --allow esbuild

# Approve multiple packages
npx npm-approve-scripts --allow esbuild,sharp,@swc/core

# Deny a package
npx npm-approve-scripts --deny untrusted-package

# List current approvals
npx npm-approve-scripts list

# Approve all currently installed packages (not recommended — audit first)
npx npm-approve-scripts --allow-all

Step 4: Commit the Allowlist

The approved scripts list gets stored in package.json under a new field, making it reproducible across environments:

{
  "name": "my-project",
  "scripts": {
    "build": "next build",
    "start": "next start"
  },
  "approvedScripts": {
    "approve": [
      "[email protected].*",
      "[email protected].*",
      "@swc/core@1.*"
    ],
    "deny": []
  }
}

Version ranges follow semver patterns. Be specific about ranges — approving [email protected].* rather than esbuild@* is safer.

Step 5: Test with npm v12 Behavior

Before v12 ships, test your pipeline with the future defaults:

# Simulate v12 behavior on npm 11
npm install --install-strategy=manual --allow-remote=none --allow-git=none

# If everything works, you're ready for v12
# If you see errors, review and approve the affected packages

For a full walkthrough of npm package safety evaluation before adding new dependencies, see the npm Package Evaluation Guide.

CI/CD Pipeline Migration

CI environments need special attention because they often run clean installs and depend on postinstall hooks for build steps. Here's how to prepare:

# GitHub Actions example — ready for npm v12
jobs:
  build:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: 'https://registry.npmjs.org'
      
      - name: Install dependencies
        run: |
          npm ci
          # If you need to allow remote tarballs temporarily:
          # npm ci --allow-remote=all
      
      - name: Build
        run: npm run build

Key CI considerations:

Package Authors: What You Should Do

If you maintain an npm package with install scripts, here's how to prepare:

Option 1: Migrate to Lifecycle Hooks

Move install-time logic to lifecycle scripts that don't run on npm install:

{
  "scripts": {
    "postinstall": "node ./setup.mjs",       // Won't run in v12
    "prepare": "node ./build.mjs",             // Runs on 'npm publish'
    "prepublishOnly": "npm run build",         // Runs before publish
    "rebuild": "node-gyp rebuild"              // Explicit, not automatic
  }
}

Option 2: Ship Prebuilt Binaries

Instead of compiling native code during install, ship prebuilt binaries for major platforms. Projects like esbuild (GOOS/GOARCH binaries) and sharp (prebuild-install) are good examples.

Monorepo Considerations

Monorepos using npm workspaces face additional complexity because each workspace may have different script requirements:

# Root package.json (workspaces root)
{
  "workspaces": ["packages/*"],
  "approvedScripts": {
    "approve": [
      "[email protected].*",
      "typescript@5.*"
    ]
  }
}

# Each workspace's approvedScripts merges with the root.
# To check all scripts across workspaces:
npm query .scripts --workspaces

The allow-remote and allow-git Flags

Besides install scripts, the allow-remote and allow-git defaults are equally important to understand:

# Allow all remote tarballs (restores current behavior)
npm install --allow-remote=all

# Allow specific remote sources (future feature)
echo 'remote-allowlist=["https://github.com/my-org/*"]' >> .npmrc

# Allow all Git dependencies (restores current behavior)
npm install --allow-git=all

# .npmrc equivalents
echo 'allow-remote=all' >> .npmrc
echo 'allow-git=all' >> .npmrc

These flags accept all (allow everything) or none (block everything). Future versions may support granular allowlists. For now, test your project with both set to none and see what breaks.

FAQ

What are the breaking changes in npm v12?
npm v12 introduces three security-related default changes: (1) install scripts (preinstall/install/postinstall) no longer run automatically — you must explicitly approve them using npm approve-scripts; (2) --allow-remote defaults to none, blocking https tarballs; (3) --allow-git defaults to none, blocking Git dependencies. All three changes are available behind warnings in npm 11.10.0+.
When will npm v12 be released?
npm v12 is estimated for release in July 2026. The June 9 GitHub Changelog confirmed these defaults will ship with the v12 major version. All changes are already testable behind warnings in npm 11.10.0+ (allow-git), 11.15.0+ (allow-remote), and 11.16.0+ (install scripts). Upgrade now to surface warnings in your project.
How do I migrate my project to npm v12?
Three-step migration: (1) Upgrade to npm 11.16.0+ and run 'npm query .scripts' to find all packages with install scripts; (2) Review each script — approve trusted packages with npx npm-approve-scripts --allow and test with --install-strategy=manual; (3) For CI pipelines, add --ignore-scripts=false temporarily or configure the allowlist in package.json. The approved allowlist should be committed to your repository for reproducibility.
What happens to node-gyp and native addons under npm v12?
Native addons that use node-gyp rely on install scripts to compile native code during 'npm install'. Under npm v12, these scripts won't run automatically. Package authors should migrate to prebuild binaries or platform-specific packages. As a temporary workaround, developers can approve known-safe packages using npm approve-scripts before install.
How does npm v12 affect CI/CD pipelines?
CI pipelines that run 'npm install' in automation will be affected if they depend on packages with install scripts (build steps, native compilation, postinstall cleanup). The recommended approach is to pre-approve trusted packages in your CI config or package.json, then run 'npm ci' as usual. For monorepos, each workspace may need its own allowlist configuration. Test your pipeline with npm 11.16.0+ first using --install-strategy=manual to surface all warnings before v12 ships.
Can I still use https tarballs and Git dependencies in npm v12?
Yes, but you must explicitly allow them. Use --allow-remote=all to restore https tarball installs and --allow-git=all for Git dependencies. For a more granular approach, you can specify individual allowed sources. These flags can be set in .npmrc per-project. The change only affects the default — explicit opt-in remains fully supported.
How is this different from npm 11's --allow-scripts or the earlier RFC?
The February 2026 RFC (covered in the npm Install Scripts Opt-In RFC analysis) proposed making install scripts opt-in. npm v12 delivers that proposal as the final default, alongside allow-remote and allow-git changes. The RFC was a proposal stage; the June 9 announcement is the final confirmed behavior. Additionally, allow-git=none closes a specific CVE where a Git dependency's .npmrc could override the Git executable. For a broader look at evaluating packages safely, see the npm Package Evaluation Guide.

Next Steps

The clock is ticking on npm v12. Every project that uses npm will be affected. The good news: you can prepare today by upgrading to npm 11.16.0+, running the audit commands above, and configuring your allowlist before the official release.

Start with npm query .scripts — it takes five seconds and tells you how much work is ahead. For most projects, the migration takes 15-30 minutes. The alternative is a broken CI pipeline in July.

Building a new Node.js project? I help teams set up secure, future-proof JavaScript architectures. Get in touch for a consultation.

Contact

Need help with your npm migration?

I help teams audit their npm setup, configure allowlists, and prepare for npm v12. Free initial consultation.