RFC: Update Node libraries to v18

If you use Node on the backend, please give feedback here or in the PRs linked below.

As part of my work of integrating node-event-emitter into the various Node libraries (a breaking change), so that my node-http2 bindings can be added to the package set, I thought there are a few other changes (breaking and non-breaking) we might want to make in this process, especially since some of these libraries’ bindings are missing.

  • format codebases with purs-tidy
  • replace all onX-style event handling with the EventHandle API I introduced in node-event-emitter@v3.0.0
  • update bindings to cover the entire modules (or at least more of it)
  • use uncurried functions for FFI
  • integrate Aff bindings into the low-level library bindings (mainly because some things are harder to do or test in some libraries (e.g. node-net) that depend on other ones (e.g. node-stream)

So far, I’ve made the following PRs, and I would like feedback on them. None implement the Aff bindings because that might be controversial :

Regardless, once the above 3 PRs settle, I can add node-tls and node-http2 to the package set sometime after that.

I think that formatting the codebases, updating bindings to cover more of the modules, and using uncurried functions in FFI are all desirable and don’t feel controversial to me. I also think that targeting Node’s last supported release (as of now, that’s Node 18) is also desirable.

At a short glance, I think the EventHandle approach is nicer than onX, though I prefer Handle as a suffix rather than HnewListenerHandle rather than newListenerH, for example. However, since I do very little event-driven work in Node I would be curious if someone like @mikesol has opinions on the API.

Integrating Aff is a little more controversial. Personally, I think each Node library should implement the low-level Effect bindings and a higher-level Aff set — as seen in node-fs and node-fs-aff — but in the same library rather than having two libraries. It’s easy to lift the Effect code up into Aff as seen in node-fs-aff, and Aff is a de facto core library at this point.


I’ve only got http left to do, but it’s a big one. Let’s just say I’m not super motivated to do all of the bindings for that one. I think I’ll just make it possible for that to compile with the below updated libraries, but not do much further.

Here’s the current changelog list. Pretty much all bindings are complete or near-complete in the below libraries. Any missing APIs I skipped were either something I didn’t care to implement or seemed unsafe to me in some way. Note: I did not attempt to add tests to the work I did, nor did anyone review most of the work I did. There may be some bugs here.

Note: towards the end of development, I had to update node-streams with a breaking change. So, the libraries that depended on that received a minor update.

As a result of integrating Aff into the lower-level libraries, these two libraries will be obsolete:

  • node-streams-aff
  • node-fs-aff
  • node-readline-aff (not a part of the purescript-node GH org)

I didn’t check node-posix-types to see if anything else needed to be done there. I believe path bindings are complete. I think url bindings are also complete…?

These node modules still don’t have bindings:

Whew! Good work! As far as worker threads go, there’s this:

node-execa has now been updated to v4: Release v4.0.0 · JordanMartinez/purescript-node-execa · GitHub

Still got http to do, but that should be about it before I see how this affects the package set.

Rather than just getting node-http to compile as was my original plan, I reimplemented its bindings. Along the way, I realized that node-url was also out-of-date, and so reimplemented those bindings as well.

So, at this point, all of the Node libs have been updated to Node v18. Now we just need to update the package set.

1 Like