Summary
perry check --check-deps flags every Node.js built-in import as error[U006]: Node.js built-in module '...' cannot be used in native compilation, regardless of whether perry-stdlib actually provides a working shim. This produces false-positive failures on code that perry compile builds and runs correctly.
This is the inverse direction of the now-closed #81 (which was: check-deps green, compile red).
Reproducer
// uses_crypto.ts
import * as crypto from "crypto"
console.log(crypto.createHash("sha256").update("x").digest("hex"))
perry compile succeeds and runs:
$ perry compile uses_crypto.ts -o uses_crypto && ./uses_crypto
Wrote executable: uses_crypto
Binary size: 0.8MB
2d711642b726b04401627ca9fbac32f5c8530fb1903cc4db02258717921a4881
perry check --check-deps fails on the same file:
$ perry check --check-deps uses_crypto.ts
error[U006]: Node.js built-in module 'crypto' cannot be used in native compilation (imported in: uses_crypto.ts)
= help: Native compilation does not support Node.js runtime APIs. Consider using a pure TypeScript implementation or removing this dependency.
Check failed: 1 error(s), 0 warning(s)
Tested with locally-built perry 0.5.493.
Root cause
crates/perry/src/commands/deps.rs :: check_node_builtin_imports (around line 477):
for import in all_imports {
if is_node_builtin(import) && !is_perry_builtin(import) {
// ... emit DiagnosticCode::UnsupportedFeature ("U006") ...
}
}
is_node_builtin (same file, line 212) returns true for all 36 Node builtin names. There is no cross-check against modules actually registered in crates/perry-stdlib/src/lib.rs, which include working implementations for at least: crypto, events, http, net, readline, streams, worker_threads, zlib, plus third-party shims (axios, fastify, ioredis, mysql2, pg, ws, nodemailer, etc.).
So the diagnostic logic encodes "all Node builtins are unsupported" while the runtime/stdlib has been moving past that for several releases.
Impact
perry check --check-deps is commonly the first signal a user gets when assessing whether a Node project can be Perry-compiled. The false positives make it look strictly worse than reality — e.g. evaluating a real codebase, the check reported 8 "unsupported" Node builtins (crypto, http, path, os, url, fs, cluster, child_process, timers/promises); the actual genuinely-unsupported ones are a smaller subset.
Suggested fix
Have is_node_builtin's callers consult an allowlist of builtins that perry-stdlib covers, and only emit U006 for the genuinely-unsupported subset (cluster, child_process, etc.). The most robust source of truth would be a small registry that perry-stdlib itself populates, rather than a hand-maintained list in deps.rs.
A short-term fix is to hardcode the known-supported set in deps.rs and emit U006 only for the difference. Either way, the existing list at line 212 should be split into unsupported_builtins and supported_via_stdlib_builtins.
Found via
Compatibility study of MedusaJS against Perry — --check-deps reported a much larger gap than what compile actually rejects.
Summary
perry check --check-depsflags every Node.js built-in import aserror[U006]: Node.js built-in module '...' cannot be used in native compilation, regardless of whetherperry-stdlibactually provides a working shim. This produces false-positive failures on code thatperry compilebuilds and runs correctly.This is the inverse direction of the now-closed #81 (which was:
check-depsgreen,compilered).Reproducer
perry compilesucceeds and runs:perry check --check-depsfails on the same file:Tested with locally-built
perry 0.5.493.Root cause
crates/perry/src/commands/deps.rs::check_node_builtin_imports(around line 477):is_node_builtin(same file, line 212) returnstruefor all 36 Node builtin names. There is no cross-check against modules actually registered incrates/perry-stdlib/src/lib.rs, which include working implementations for at least:crypto,events,http,net,readline,streams,worker_threads,zlib, plus third-party shims (axios,fastify,ioredis,mysql2,pg,ws,nodemailer, etc.).So the diagnostic logic encodes "all Node builtins are unsupported" while the runtime/stdlib has been moving past that for several releases.
Impact
perry check --check-depsis commonly the first signal a user gets when assessing whether a Node project can be Perry-compiled. The false positives make it look strictly worse than reality — e.g. evaluating a real codebase, the check reported 8 "unsupported" Node builtins (crypto,http,path,os,url,fs,cluster,child_process,timers/promises); the actual genuinely-unsupported ones are a smaller subset.Suggested fix
Have
is_node_builtin's callers consult an allowlist of builtins thatperry-stdlibcovers, and only emit U006 for the genuinely-unsupported subset (cluster,child_process, etc.). The most robust source of truth would be a small registry thatperry-stdlibitself populates, rather than a hand-maintained list indeps.rs.A short-term fix is to hardcode the known-supported set in
deps.rsand emit U006 only for the difference. Either way, the existing list at line 212 should be split intounsupported_builtinsandsupported_via_stdlib_builtins.Found via
Compatibility study of MedusaJS against Perry —
--check-depsreported a much larger gap than whatcompileactually rejects.