You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Backend-agnostic abstraction for File System operations? #87
Hi! I'm currently working on a transpiler for PHP, and we're implementing FFI for standard I/O operations.
Currently, the ecosystem relies heavily on purescript-node-fs (with Node.FS.* modules). To allow existing PureScript code to run on PHP without modification, I had to create a polyfill by mocking this package and its modules, which I forked here.
Having "Node" hardcoded in the module namespaces feels a bit abnormal for alternative backends, even if I truly understand the historical reasons behind. I wonder if there are any long-term plans to create a more agnostic, generic package (e.g., purescript-fs or System.FS) with typeclasses/interfaces, which node-fs, erl-fs or phpurs-fs could then implement?
Just wanted to open the discussion on how alternative backends should gracefully handle these Node-specific namespaces!
I don't know of any plans to do so, but seems like a reasonable project - it's a similar situation to purescript-argonaut vs purescript-json.
Do you have Aff in PHP? I've not used it in like 20 years but I've never heard of it having async capabilities, so that might be a bit of a sticking point - matching Aff's semantics is a big project in its own right most likely, and Node.FS.Aff would generally be the most common way people use this library.
I guess one option would be to make the FS library parametric over the effect type, and then provide Effect / Aff instances according to what makes sense for a specific backend. That might result in a different set of compatibility issues, if downstream libraries assume the existence of a concrete instance for MonadFS or whatever it would be called, but it would be better than the current situation I think.
Thanks for your feedback! It's great to hear that a backend-agnostic abstraction is something the community would be open to.
My issue was more of a semantic discussion at first:
I completely understand your concern! PHP has historically been strictly synchronous. However, modern PHP (8.1+) introduced Fibers, and the ecosystem now has a robust, production-ready async event loop (Revolt/EventLoop and AMPHP).
Because of this, we actually do have full Aff support! We built phpurs-aff which maps PureScript's Aff semantics perfectly to PHP's Fibers. So for File System operations, we didn't need to fallback to synchronous Effect; we implement System.FS.Aff using PHP's non-blocking file I/O libraries, keeping the exact same async behavior as Node.js. Check this out: it's run by PHP too. It's just slower, but that's ok, given the actual goal of phpurs. I discussed that here.
A generic typeclass-based abstraction like MonadFS would definitely be the icing on the cake for the ecosystem. But to be honest, having to adapt and mock the existing node-fs as it currently stands was actually a very positive constraint: it really pushed me to build a solid FFI around Revolt, ensuring we provide a faithful and identical experience to the Aff abstraction, whatever the transpilation target.
@0x000000000000000000001 first of all, big props for PHP backend; I'm very happy to see new ones pop up 🙂
I stumbled on this as well for benchmarking/bootstrapping/etc my Racket backend, so I put together a backend-agnostic library that would work for all backends with minimal FFI, much in the spirit of purescript-json.
It has Effect and Aff, but the two could be split in separate libraries.
I am in the process of polishing and publishing all the code related to the Racket backend, will ping here when that is public.
In general I think that, with all the new backends popping up lately, we should be moving away from these node-specific libraries and pay more attention to being agnostic so that new backends can be more compatible with the rest of the ecosystem.
Thanks @f-f, that's amazing news! Big props for the Racket backend too!
I completely agree with your take: with the recent rise of alternative backends, abstracting away from Node.js specifics is definitely the way forward.
Thanks for the ping! I'll gladly jump in and continue to contribute to that ecosystem.
PureScript has more than one trick up its sleeve, but I think this is one of its greatest strengths for public visibility. It completely bypasses the traditional "which language is best" comparisons (where giant corporate ecosystems naturally dominate the conversation, with their powerful marketing budgets) and brings something entirely different to the table (see snapshot).
I try to drop a few ideas here and there, little by little, along those lines. I noticed a spike in views on my profile after posting messages like that. Because it piques people’s curiosity.
So I think that, even though this is far from the only direction for development of PureScript, moving in this direction will generate even more interest and increase the adoption rate. ⭐️
I wonder if the time might be right to officially present PureScript as a runtime-agnostic solution on the showcase website? We could even display the compiled code in different languages in the sandbox!
I may have stirred things up a bit (?), but if it comes to that, I can offer to look into it over the next few months, if things go well. Feel free to reach out to me if needed.
I'm also making progress on a more ambitious project, one that's potentially more interesting for the PureScript community itself (as opposed to developers from other worlds, like PHP): gopurs
It supports quite a few things: uncurried FFI, Aff, very good performance, etc.
But I inevitably ended up doing the same thing as I did for phpurs. If the project proves useful to a significant number of PureScript developers, it may undoubtedly be a good opportunity to standardize these topics. Of course, I'll be willing to help. 🙂
Activity
garyb commentedon Jul 7, 2026
I don't know of any plans to do so, but seems like a reasonable project - it's a similar situation to
purescript-argonautvspurescript-json.Do you have
Affin PHP? I've not used it in like 20 years but I've never heard of it having async capabilities, so that might be a bit of a sticking point - matchingAff's semantics is a big project in its own right most likely, andNode.FS.Affwould generally be the most common way people use this library.I guess one option would be to make the FS library parametric over the effect type, and then provide
Effect/Affinstances according to what makes sense for a specific backend. That might result in a different set of compatibility issues, if downstream libraries assume the existence of a concrete instance forMonadFSor whatever it would be called, but it would be better than the current situation I think.0x000000000000000000001 commentedon Jul 7, 2026
Thanks for your feedback! It's great to hear that a backend-agnostic abstraction is something the community would be open to.
My issue was more of a semantic discussion at first:
I completely understand your concern! PHP has historically been strictly synchronous. However, modern PHP (8.1+) introduced Fibers, and the ecosystem now has a robust, production-ready async event loop (
Revolt/EventLoopandAMPHP).Because of this, we actually do have full
Affsupport! We builtphpurs-affwhich maps PureScript'sAffsemantics perfectly to PHP's Fibers. So for File System operations, we didn't need to fallback to synchronousEffect; we implementSystem.FS.Affusing PHP's non-blocking file I/O libraries, keeping the exact same async behavior as Node.js. Check this out: it's run by PHP too. It's just slower, but that's ok, given the actual goal ofphpurs. I discussed that here.A generic typeclass-based abstraction like
MonadFSwould definitely be the icing on the cake for the ecosystem. But to be honest, having to adapt and mock the existingnode-fsas it currently stands was actually a very positive constraint: it really pushed me to build a solid FFI aroundRevolt, ensuring we provide a faithful and identical experience to theAffabstraction, whatever the transpilation target.f-f commentedon Jul 8, 2026
@0x000000000000000000001 first of all, big props for PHP backend; I'm very happy to see new ones pop up 🙂
I stumbled on this as well for benchmarking/bootstrapping/etc my Racket backend, so I put together a backend-agnostic library that would work for all backends with minimal FFI, much in the spirit of
purescript-json.It has
EffectandAff, but the two could be split in separate libraries.I am in the process of polishing and publishing all the code related to the Racket backend, will ping here when that is public.
In general I think that, with all the new backends popping up lately, we should be moving away from these node-specific libraries and pay more attention to being agnostic so that new backends can be more compatible with the rest of the ecosystem.
0x000000000000000000001 commentedon Jul 8, 2026
Thanks @f-f, that's amazing news! Big props for the Racket backend too!
I completely agree with your take: with the recent rise of alternative backends, abstracting away from Node.js specifics is definitely the way forward.
Thanks for the ping! I'll gladly jump in and continue to contribute to that ecosystem.
PureScript has more than one trick up its sleeve, but I think this is one of its greatest strengths for public visibility. It completely bypasses the traditional "which language is best" comparisons (where giant corporate ecosystems naturally dominate the conversation, with their powerful marketing budgets) and brings something entirely different to the table (see snapshot).
I try to drop a few ideas here and there, little by little, along those lines. I noticed a spike in views on my profile after posting messages like that. Because it piques people’s curiosity.
So I think that, even though this is far from the only direction for development of PureScript, moving in this direction will generate even more interest and increase the adoption rate. ⭐️
0x000000000000000000001 commentedon Jul 8, 2026
Oh, and I forgot: I also discussed that with Nathan here
0x000000000000000000001 commentedon Jul 8, 2026
I wonder if the time might be right to officially present PureScript as a runtime-agnostic solution on the showcase website? We could even display the compiled code in different languages in the sandbox!
0x000000000000000000001 commentedon Jul 10, 2026
I may have stirred things up a bit (?), but if it comes to that, I can offer to look into it over the next few months, if things go well. Feel free to reach out to me if needed.
👋 🤟
0x000000000000000000001 commentedon Aug 2, 2026
I'm also making progress on a more ambitious project, one that's potentially more interesting for the PureScript community itself (as opposed to developers from other worlds, like PHP):
gopursIt supports quite a few things: uncurried FFI, Aff, very good performance, etc.
But I inevitably ended up doing the same thing as I did for
phpurs. If the project proves useful to a significant number of PureScript developers, it may undoubtedly be a good opportunity to standardize these topics. Of course, I'll be willing to help. 🙂