Repository navigation
Description
Summary
Node exposes child_process._forkChild(fd, serializationMode) as an enumerable function on the node:child_process namespace. Perry's child-process surface now includes fork() and IPC-related work, but _forkChild itself is absent from the manifest, generated declarations, and native namespace callable list.
This is an internal/legacy export, but it is part of Node's observable Object.keys(require("node:child_process")) surface and is used by Node's child-process IPC bootstrap path to install process.send() / channel handling in forked children.
Expected Node behavior
With Node v25.9.0:
const cp = require("node:child_process");
console.log(Object.keys(cp)); // includes "_forkChild"
console.log(Object.prototype.propertyIsEnumerable.call(cp, "_forkChild")); // true
console.log(typeof cp._forkChild); // "function"
console.log(cp._forkChild.length); // 2
console.log(cp._forkChild.name); // "_forkChild"Calling the helper participates in Node's IPC child bootstrap and expects an IPC fd plus serialization mode; invalid direct calls throw from that bootstrap path rather than resolving to undefined.
Current Perry evidence
On origin/main:
crates/perry-api-manifest/src/entries.rsregisterschild_process.exec,execSync,execFile,execFileSync,spawn,spawnSync,fork,ChildProcess, and the Node-undefinedStreamcompatibility property, but no_forkChildentry.crates/perry-runtime/src/object/native_module.rs::is_native_module_callable_export()lists the same child-process callable exports but omits("child_process", "_forkChild").- Source search across
crates,docs,test-files, andtest-parityfinds no_forkChild/forkChildimplementation, declaration, or fixture. - Existing child-process work such as merged PR feat(node:child_process): async spawn reactor, fork()+IPC, exec error/encoding parity (#1933–#1938) #1955 covers async spawn,
fork()+ IPC, and exec parity, while open node:child_process: honor spawn and exec option semantics beyond cwd/env/shell #2555 is about spawn/exec option semantics; neither tracks this namespace helper export.
I did not use a current-tree target/release/perry binary for this check; this is Node-probe plus current source evidence.
Suggested test surface
Add a small shape fixture under test-parity/node-suite/child_process/:
import * as cp from "node:child_process";
console.log("_forkChild enumerable:", Object.prototype.propertyIsEnumerable.call(cp, "_forkChild"));
console.log("_forkChild type:", typeof cp._forkChild);
console.log("_forkChild length:", cp._forkChild?.length);
console.log("_forkChild name:", cp._forkChild?.name);If a minimal implementation is added before full IPC bootstrap behavior, the fixture can stay shape-only and a follow-up can cover valid fd/serialization behavior.
Scope / non-goals
- Scope: expose the enumerable
_forkChildfunction shape on thechild_processnamespace, generated declarations/reference docs, and captured-property reads. - Scope: eventually route valid calls into the child IPC bootstrap path if Perry needs parity for Node forked-child startup.
- Non-goal: changing
child_process.fork()lifecycle behavior or spawn/exec option semantics (node:child_process: honor spawn and exec option semantics beyond cwd/env/shell #2555). - Non-goal: reintroducing
child_process.Stream; current source comments correctly note Node returnsundefinedfor that name in current Node.
Activity
andrewtdiz commentedon Jun 2, 2026
Taking this with #2556 and #3316 as a focused node:child_process lifecycle/IPC surface PR cut. Planned scope: ChildProcess Symbol.dispose dispatch, _forkChild enumerable export shape, and subprocess.send callback/closed-channel observable semantics. Non-goals: broad spawn/exec option semantics (#2555), setup arg validation (#3079), and child-side process IPC surface (#2529) unless a minimal helper is required for the selected tests.
andrewtdiz commentedon Jun 2, 2026
Implemented in draft PR #4110.