Skip to content

NodeJS Compat: process features#4271

Merged
guybedford merged 21 commits intomainfrom
gbedford/process-features
Jun 13, 2025
Merged

NodeJS Compat: process features#4271
guybedford merged 21 commits intomainfrom
gbedford/process-features

Conversation

@guybedford
Copy link
Contributor

@guybedford guybedford commented Jun 6, 2025

Here's an initial stab at better process support.

For process.versions, we just include the node version maintained through a header file that will need to be manually updated. I included the version information for node, v8, icu, ada, brotli, simdutf, sqlite, nbytes, ncrypto as part of the Bazel build process. This exposes internal implementation details which might be considered a security risk. This is also what all Node-like platforms do.

We can discuss restricting this list down to just node and v8 or even just node. process.versions.node is a common compat check though so it's worth bearing that one in mind at least. Happy to remove, not tied to the implementation at all, would value feedback here.

Included Features

Properties:

  • process.platform - Returns OS platform (before returned darwin/linux/win32, now always returns linux)
  • process.arch - System architecture (always returns x64)
  • process.version - Node.js version string, hard coded in a header file, and will need to be updated to the running latest stable release as appropriate.
  • process.versions - Version info for node matching process.version
  • process.title - Process title (hardcoded to "workerd")
  • process.features - Feature flags object (as previously)
  • process.argv - Command line arguments array (hardcoded to ["workerd"])
  • process.argv0 - First argument (hardcoded to "workerd")
  • process.execArgv - Node.js specific arguments (empty array)
  • process.pid - Process ID (hardcoded to 1)
  • process.ppid - Parent process ID (hardcoded to 0)
  • process.release - Node.js release metadata, hardcoded to Node.js default (this is what Bun & Deno do, open to leaving this out as well) (removed)
  • process.config - Build configuration object (empty but just has properties for checking per Node compat)
  • process.allowedNodeEnvironmentFlags - Empty Set for environment flags

Methods:

  • process.getegid/geteuid/getgid/getuid() - Get effective group/user ID (returns 0)
  • process.setegid/seteuid/setgid/setuid() - Set effective group/user ID permission error
  • process.setgroups, getgroups() - permission error
  • process.initgroups - permission error
  • process.setSourceMapsEnabled() - Enable source maps (no-op)
  • process.getSourceMapsSupport() - returning false for all properties
  • process.kill - throws unsupported
  • process.ref - throws unsupported
  • process.unref = throws unsupported
  • process.uptime - returning 0 currently, may update to be request time based
  • process.hrtime - returns the same time as Date.now()
  • process.hrtime.bigint - bigint variation of process.hrtime
  • process.uptime - always returns 0
  • process.emitWarning and process now extends event emitter with "on" support, enabled the former util test.
  • kill() - throws unsupported
  • exit() - as previously implemented
  • abort() - as exit(0)

Events

  • warning on process.emitWarning
  • rejectionHandled per the current global event
  • unhandledRejection per the current global event

Follow-on Features

The following features will be implemented as follow-ons:

  • process.umask - Added as unsupported pending FS work
  • process.chdir - Added as unsupported pending FS work
  • process.cwd - Added as unsupported pending FS work
  • stderr / stdin / stdout - to implement as follow-up

Excluded Features

The following features are still entirely omitted and only exported as undefined:

  • exitCode
  • channel
  • connected
  • binding()
  • debugPort - possible for follow-up, would need to track debug port configuration
  • dlopen()
  • finalization
  • getActiveResourcesInfo()
  • setUncaughtExceptionCaptureCallback()
  • hasUncaughtExceptionCaptureCallback()
  • memoryUsage()
  • noDeprecation
  • permission
  • release - deemed unnecessary
  • report
  • resourceUsage()
  • send()
  • traceDeprecation - undefined unless set anyway
  • throwDeprecation - undefined unless set anyway
  • sourceMapsEnabled - experimental and already deprecated, so skipped
  • threadCpuUsage() - added after Node.js 20
  • Events: beforeExit, disconnect, exit, message, multipleResolves, workerMessage, uncaughtException, uncaughtExceptionMonitor, worker

@guybedford guybedford requested review from a team as code owners June 6, 2025 18:05
@guybedford guybedford requested a review from a team June 6, 2025 18:05
Copy link
Contributor

@windsurf-bot windsurf-bot bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other comments (2)
  • WORKSPACE (226-226) The call to `extract_versions(node_version = NODE_VERSION)` depends on `NODE_VERSION` being defined above. Consider adding a comment to clarify this dependency, to prevent accidental reordering that could break the build.
  • src/workerd/api/node/util.h (165-165) The removal of processPlatform and getProcessPlatform() eliminates a utility for determining the platform string in a cross-platform way. If this functionality is still needed for Node.js compatibility, consider reimplementing it or providing it in another module.
1 file skipped due to size limits:
  • src/workerd/api/node/tests/util-nodejs-test.js

💡 To request another review, post a new comment with "/windsurf-review".

@guybedford guybedford force-pushed the gbedford/process-features branch from b2f4b19 to a904d28 Compare June 6, 2025 18:49
@vicb
Copy link
Contributor

vicb commented Jun 6, 2025

process.versions.node is a common compat check though so it's worth bearing that one in mind at least

FYI process.versions.node has been implemented in unenv because quite a few libs rely on that being set. It was released a few weeks back.

I think that was the right thing to do even if we broke other (older) libs along the way, i..e cloudflare/workers-sdk#9352

/cc @mikenomitch @anonrig

@guybedford
Copy link
Contributor Author

@vicb am I understanding correctly that your shim caused this to pass in your workers apps, therefore you've effectively already tested "turning on" these feature gates? Are there more cases to worry about that rely on other compat features being available (e.g. should we hold back on this for FS to fully land?). The feedback is definitely good to know in terms of the risk assessment of this PR as well.

@guybedford guybedford force-pushed the gbedford/process-features branch from 05cbd0e to b1c3940 Compare June 6, 2025 21:41
@danlapid
Copy link
Collaborator

danlapid commented Jun 7, 2025

process.platform - Returns OS platform (darwin/linux/win32) - [Dan]: should likely always be linux, users dont need to know which OS their workers run on
process.arch - System architecture (x64/arm64/ia32) - [Dan]: should likely always be x64, there might be certain exploits that only work on x64/arm/... machines and attackers might want to target specific production machines, we shouldn't le them.
process.version - Node.js version string - [Dan]: dunno what the right answer is here and afraid upgrading this will be a breaking change but leaving it old will also be bad.
process.versions - Version info for node, v8, icu, ada, brotli, simdutf, sqlite, nbytes, ncrypto - [Dan]: This is all internal details, I don't think we should expose any of it.
process.title - Process title (hardcoded to "workerd")
process.features - Feature flags object
process.argv - Command line arguments array - [Dan]: Where is this populated from? this sounds really bad if in prod all workers will have our command like arguments
process.argv0 - First argument (hardcoded to "node") - [Dan]: why not workerd?
process.execArgv - Node.js specific arguments (empty array)
process.pid - Process ID (hardcoded to 1)
process.ppid - Parent process ID (hardcoded to 0)
process.release - Node.js release metadata, hardcoded to Node.js default (this is what Bun & Deno do, open to leaving this out as well) - [Dan]: same as above, afraid that updating this will be a breaking change.
process.config - Build configuration object (empty but just has properties for checking per Node compat)
process.allowedNodeEnvironmentFlags - Empty Set for environment flags

@guybedford
Copy link
Contributor Author

With the version, typeof process.versions.node === 'string' is a very common compat check for Node compat. For this reason alone this PR will likely cause functional changes for many libraries as already mentioned by @vicb.

For the platform - we were already supporting in local workerd providing the native platform information. I've removed this, but in theory that is a breaking change for non edge worker users.

I've reduced the version list to just node now, with a manually maintained version. I've also updated the argv to use workerd instead of node, which definitely makes more sense to me.

@guybedford guybedford force-pushed the gbedford/process-features branch from 835ac7d to 467c047 Compare June 7, 2025 01:32
@github-actions
Copy link

github-actions bot commented Jun 7, 2025

The generated output of @cloudflare/workers-types matches the snapshot in types/generated-snapshot 🎉

@vicb
Copy link
Contributor

vicb commented Jun 7, 2025

therefore you've effectively already tested "turning on" these feature gates?

We have process.versions.node define in OpenNext for probably a couple months. It landed in unenv more recently in Wrangler 4.16.

@guybedford guybedford force-pushed the gbedford/process-features branch from 317e175 to 565d2d4 Compare June 9, 2025 16:12
@guybedford guybedford force-pushed the gbedford/process-features branch from 9b88267 to 374159e Compare June 12, 2025 21:37
@claude

This comment was marked as off-topic.

@guybedford
Copy link
Contributor Author

This PR is ready for final review, with the immediate follow-ups remaining being chdir, cwd, stdin, stdout and stderr.

@claude

This comment was marked as off-topic.

Copy link
Member

@npaun npaun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process.platform implementation LGTM

@guybedford guybedford merged commit 3edffd2 into main Jun 13, 2025
31 of 33 checks passed
@guybedford guybedford deleted the gbedford/process-features branch June 13, 2025 00:23
vickykont added a commit that referenced this pull request Jun 16, 2025
danlapid added a commit that referenced this pull request Jun 16, 2025
…ures

Revert "NodeJS Compat: process features (#4271)"
guybedford added a commit that referenced this pull request Jun 16, 2025
guybedford added a commit that referenced this pull request Jun 16, 2025
guybedford added a commit that referenced this pull request Jun 17, 2025
guybedford added a commit that referenced this pull request Jun 18, 2025
guybedford added a commit that referenced this pull request Jun 18, 2025
danlapid added a commit that referenced this pull request Jun 20, 2025
guybedford added a commit that referenced this pull request Jul 2, 2025
guybedford added a commit that referenced this pull request Jul 2, 2025
guybedford added a commit that referenced this pull request Jul 2, 2025
guybedford added a commit that referenced this pull request Jul 2, 2025
guybedford added a commit that referenced this pull request Jul 2, 2025
guybedford added a commit that referenced this pull request Jul 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants