Skip to content
Latchkey

Node "punycode module is deprecated" DEP0040 Warning - Fix in CI

Node 21+ emits [DEP0040] The punycode module is deprecated when a dependency imports the built-in punycode. It is a warning, not an error - but it clutters CI logs and, with --throw-deprecation, can fail a step.

What this error means

CI logs show (node:NNN) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead. It typically comes from a transitive dependency (e.g. an older URI/whatwg library), not your own code.

Node output
(node:12345) [DEP0040] DeprecationWarning: The `punycode` module is deprecated.
Please use a userland alternative instead.
    (Use `node --trace-deprecation ...` to show where the warning was created)

Diagnose it: which registry, and with what credentials?

Registry errors are resolved in a precedence chain, and the effective value is rarely the one in the file you are looking at. Scoped registries, .npmrc files at several levels, and environment variables all combine before a request is made.

Terminal
# the effective, fully merged configuration
npm config list -l | grep -E "registry|_auth|always-auth"

# where each value came from
npm config get registry
npm config get @yourscope:registry

# prove the token works, independently of the install
curl -sI -H "Authorization: Bearer $NPM_TOKEN" \
  "$(npm config get registry)@yourscope%2fpackage" | head -1

Common causes

A transitive dependency imports the built-in punycode

An older library still requires Node’s deprecated punycode builtin. On Node 21+ that import triggers DEP0040 on every run.

A strict deprecation flag turns it fatal

Running with --throw-deprecation (or NODE_OPTIONS=--throw-deprecation) escalates the warning into a thrown error that fails the step.

How to fix it

Trace and upgrade the source dependency

Find which dependency imports punycode and upgrade it to a version that uses a userland alternative.

Terminal
node --trace-deprecation node_modules/.bin/<your-cli>
# or pinpoint the dependency:
npm ls punycode
npm install <offending-parent>@latest

Silence intentionally if you cannot upgrade yet

  1. Confirm the warning is from a third-party dependency, not your code.
  2. If you must quiet logs, set NODE_NO_WARNINGS=1 only where appropriate - it hides all warnings, so use sparingly.
  3. Track the upstream issue and remove the suppression once upgraded.

How to prevent it

  • Upgrade dependencies that import deprecated builtins.
  • Avoid --throw-deprecation in CI until sources are clean.
  • Trace deprecations with --trace-deprecation to find the origin.

Frequently asked questions

What causes Node "punycode module is deprecated" DEP0040 warning?
There are 2 common causes: a transitive dependency imports the built-in punycode and a strict deprecation flag turns it fatal. An older library still requires Node’s deprecated punycode builtin.
How do I fix Node "punycode module is deprecated" DEP0040 warning?
There are 2 fixes depending on which cause you have: trace and upgrade the source dependency and silence intentionally if you cannot upgrade yet. Work through them in order, since the first is the most common.
What does Node "punycode module is deprecated" DEP0040 warning actually mean?
CI logs show (node:NNN) [DEP0040] DeprecationWarning: The punycode module is deprecated.
How do I stop Node "punycode module is deprecated" DEP0040 warning happening again?
Upgrade dependencies that import deprecated builtins. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

This is a registry failure, not a bug in your code. Latchkey detects, repairs, and retries it for you. Start free → 30-day trial · No credit card