Hi folks!
I’d like to share a project I’ve been working on: a WebAssembly backend for PureScript.
You can see the codebase including some examples, documentations and benchmarks here:
https://github.com/purs-wasm/purescript-backend-wasm
Actually, I tried to take on the same challenge about three years ago, but at the time it didn’t go very far due to my lack of compiler development experience. Since then, though, I’ve spent a lot of time studying compiler theory, building a few language implementations of my own, and—perhaps most importantly—the arrival of coding agents (honestly, that’s probably been the biggest factor
). With all of that behind me, the project is finally moving again!
It’s still very much at the proof-of-concept stage, but it’s already capable of handling a fair amount of PureScript:
-
Higher-order recursive functions and partial application—the essentials of functional programming
- ADTs, pattern matching, arrays, and records
- Typeclass polymorphism
- Full Prelude support
- A few optimizations such as typeclass dictionary elimination and primitive inlining (still a work in progress!)
There’s still a long way to go before it’s truly practical, but given how quickly things have been progressing over the last few days, I’m starting to think it won’t be too long before we can write reasonably sized applications in PureScript, compile them to wasm binary, and run them from browser or node host environment.
I’ll keep working on it and share more updates as things progress. So please stay tuned!
5 Likes
I’m glad to see this being built. I’ve personally been looking for something like this for years now. Thanks for taking it on. Good luck!
2 Likes
Bring it on!
Post must be at least 20 characters.
3 Likes
i’m thrilled to announce the v0.1 release of purs-wasm! 


You can install it via npm:
npm i -g purs-wasm
Or via Nix if you prefer:
nix run github:purs-wasm/purescript-backend-wasm#purs-wasm -- build -e Main
Documentation for both app developers and future contributors is available at https://purs-wasm.github.io/documentation*
Please note that this is still a very early alpha release with several limitations, but you can already use it to compile your PureScript applications to WebAssembly.
If you run into any issues or unexpected behavior, please let us know by opening an issue!
2 Likes
I decided to take a look and ended up building a WASM branch of my SHA3 module. The requirements of SHA3 uncovered some missing bitwise operators for Integers. So, I forked and added those.
Then, in attempting to benchmark my SHA3 implementation, I uncovered some foreign effects being silently dropped. So, I drilled down and carefully fixed that and built some tests to prevent regressions (since those failures were not covered by tests). I then opened a pull request and tried to fulfill all of the requirements and guidelines including regression tests and benchmarks against the snapshot.
Looks good! Hopefully more people will come along and slowly wear the rough edges away.
It was definitely a learning experience. If I crammed too much into one PR, I apologize. The changes just kept piling up and I can’t/don’t quit until things work better or the same as before I started.
I’ll keep trying to use it in places that make sense and submitting pull requests as I think of them.
Thanks for building this!
3 Likes
Thank you for opening the first community contributor PR to purs-wasm!
It’s also really exciting to hear that you’re already using it in your PureScript projects — that means a lot 
I’ve merged the PR. Thanks again, and I’m looking forward to seeing more feedback and contributions in the future!
2 Likes
No problem! It’s truly an honor to be part of the first community contribution on such a cool/necessary project.
Here’s where I used it this week: purescript-sha3/src at wasm · rowtype-yoga/purescript-sha3 · GitHub
Quick digression:
I’ve been implementing the SHA3 algorithm to help me learn about alternative back ends and benchmark them against each other. It’s nice to have those NIST test vectors to verify against. I personally think that it’s important for Purescript to grow beyond the restrictions of JavaScript even though it may never truly escape it. WASM is a huge step in that direction…as well as the Chez Scheme backend and the others I haven’t yet tried. The racket version of the compiler is another one that piques my interest. THAT’s how good metaprogramming looks.
1 Like
Thank you! Getting benchmark results from a real, practical implementation like SHA3 — rather than a toy project — and seeing purs-wasm used and compared against other backends is incredibly concrete and valuable feedback for me.
I’m happy to see that the no-FFI version is already about 7× faster than JS.
At the same time, the reality that the Chez native FFI version is still nearly 50× faster is honestly motivating as well. Surpassing that may be difficult, but I definitely want to keep pushing to close the gap.
As for obvious areas where purs-wasm still has room to grow, support for things like Int64 and specialized containers such as I32Array / F64Array look like promising directions that we can probably experiment with relatively soon.
2 Likes
That’s sublime work @katsujukou. Probably one of my favorite repos ever.
2 Likes
(Int64, I32Array, and F64Array in base)
And a branch where I added both as well as a bootstrap command/shellhook to prevent non-deterministic behavior for anyone that would clone this repo. It is now fully tested and is verified with no regression from the snapshots benchmark:
My personal goal is to get that SHA3 algorithm as close as possible to the Chez-Scheme benchmark by end of next week. According to my estimates, Purescript-wasm can get to (at best) 50% of chez-scheme backend’s performance (thank you, Cisco) but probably not better than that. 
2 Likes
I added some more primitives and low-hanging fruit in my forks to squeeze some more performance out of WASM. Basically, I’ll end up writing four different pull requests (maybe I can compress it into two):
I ended up achieving my goal for the week of getting SHA3 to run a solid benchmark against the other backends. Nothing beats Chez-Scheme’s 60.6 MB/s but purs-wasm comes super close to native NodeJS speeds.
2 Likes
Congrats! That’s super good news @harryprayiv
2 Likes
That’s a really exciting benchmark result! I’m honestly surprised to see Node + native FFI already within reach for us.
Also, thank you for continuing to send PRs — I really appreciate it!
Unfortunately, work has been keeping me a bit busier lately, so I haven’t been able to dedicate as much time to purs-wasm development as before. I’ll get to reviewing and merging them soon, so please bear with me for a little while.
P.S.
Recently, alongside purs-wasm development, I’ve started working toward another ambitious idea again.
That one might catch your interest too 
2 Likes
This is really exciting work!
I’m planning to try running these benchmarks against your backend myself at some point to see if it supports all the test cases, once mature. However, please feel free to beat me to it and open a PR or an issue on the repo if you’d like!
1 Like