Skip to content
Latchkey

Node "Cannot find module 'node:crypto'" - Fix node: Builtins on Old Node in CI

The node: import prefix (e.g. node:crypto, node:fs) is only recognized by newer Node versions. On an older runner Node, the resolver treats node:crypto as a missing package and throws.

What this error means

Code or a dependency importing node:crypto (or node:fs, node:path, …) fails with Cannot find module 'node:crypto' in CI, while it works locally on a newer Node. The tell is the node: prefix and an older runner Node.

Node output
Error: Cannot find module 'node:crypto'
Require stack:
- /app/dist/index.js
    at Function._resolveFilename (node:internal/modules/cjs/loader)
    ... code: 'MODULE_NOT_FOUND'

Diagnose it: what is different about the runner?

A build that passes locally and fails on a runner differs in a small number of predictable ways. Check those before changing build configuration, because the build config is usually not the thing that changed.

.github/workflows/ci.yml
- run: |
    node --version && npm --version
    echo "NODE_ENV=$NODE_ENV  CI=$CI"
    nproc && free -h && df -h /
    ls -la node_modules/.bin | head

Common causes

Runner Node is too old for the node: scheme

The node: builtin prefix is supported from Node 14.18/16+. On an older runner Node, node:crypto is unresolved and throws MODULE_NOT_FOUND.

A dependency upgraded to node: imports

A bumped dependency now uses node:-prefixed builtins; if CI still runs an older Node, that dependency cannot load.

How to fix it

Upgrade CI Node to a supported version

Run a Node version that recognizes the node: builtin scheme.

Workflow
- uses: actions/setup-node@v4
  with:
    node-version: 20
- run: node --version

Align Node with your dependencies

  1. Set engines.node and .nvmrc to a version supporting node: builtins.
  2. Upgrade Node in CI when a dependency adopts node: imports.
  3. Keep local, CI, and prod Node versions in sync.

The three that account for most of them

  • Case sensitivity. Linux runners are case sensitive, macOS is not. An import with the wrong case resolves locally and fails in CI.
  • Out of memory. Exit code 137 is a SIGKILL from the kernel, not a build error. Raise --max-old-space-size or use a larger runner.
  • devDependencies pruned. NODE_ENV=production makes npm ci skip devDependencies, so the build tool itself goes missing. Set it after install, not before.

How to prevent it

  • Run a current Node LTS in CI.
  • Declare engines.node and use .nvmrc/setup-node.
  • Bump Node when dependencies require newer builtins.

Frequently asked questions

What causes Node "Cannot find module 'node:crypto'"?
There are 2 common causes: runner node is too old for the node: scheme and a dependency upgraded to node: imports. The node: builtin prefix is supported from Node 14.18/16+.
How do I fix Node "Cannot find module 'node:crypto'"?
There are 2 fixes depending on which cause you have: upgrade ci node to a supported version and align node with your dependencies. Work through them in order, since the first is the most common.
What does Node "Cannot find module 'node:crypto'" actually mean?
Code or a dependency importing node:crypto (or node:fs, node:path, …) fails with Cannot find module 'node:crypto' in CI, while it works locally on a newer Node.
How do I stop Node "Cannot find module 'node:crypto'" happening again?
Run a current Node LTS in CI. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card