nodejs/node · critical · Error

The programmatic API was removed in npm v8.0.0

Error message

The programmatic API was removed in npm v8.0.0

What it means

npm v8+ removed its programmatic Node API. The entrypoint (deps/npm/index.js) only runs the CLI when invoked directly (require.main === module); requiring 'npm' from another module lands in the else branch and throws. The package is now CLI-only by design.

Source

Thrown at deps/npm/index.js:4

if (require.main === module) {
  require('./lib/cli.js')(process)
} else {
  throw new Error('The programmatic API was removed in npm v8.0.0')
}

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Spawn the CLI as a child process instead (e.g. execa('npm', ['install']) or child_process.spawn('npm', args, { stdio: 'inherit' }))
  2. For dependency-tree work use @npmcli/arborist; for package fetching use pacote; for registry access use npm-registry-fetch; for config use @npmcli/config
  3. If you only need npm's version, read require('npm/package.json').version (a static JSON file, not the entrypoint)
  4. For exact legacy behavior, pin an older npm (v7) in a dedicated environment

Example fix

// before
const npm = require('npm')
npm.load(() => npm.commands.install(['lodash']))

// after
const { spawn } = require('child_process')
spawn('npm', ['install', 'lodash'], { stdio: 'inherit' })
Defensive patterns

Strategy: validation

Validate before calling

// Detect before requiring: read the package metadata without invoking the entrypoint
const npmPkg = require('npm/package.json')
const major = Number(npmPkg.version.split('.')[0])
if (major >= 8) {
  throw new Error(`npm@${npmPkg.version} has no programmatic API; spawn the CLI instead`)
}

Type guard

// Node has no static type for this; guard at runtime on the resolved package version
function hasProgrammaticApi(npmVersion) {
  const major = Number(String(npmVersion).split('.')[0])
  return major < 8
}

Prevention

When it happens

Trigger: Calling require('npm') or import 'npm' from a Node script, build tool, or test harness. Anything that loads the package without executing it as the main module hits the else branch.

Common situations: Migrating tooling off npm v7 or earlier that drove npm in-process; scripts that did require('npm')({ argv: [...] }) to run commands; plugins that imported npm to read its version or config.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/8338150a16527ee3. Report an issue: GitHub.