GHCi in the Browser

Posted on 3 July 2024
Tags: ,

I’m happy to announce that you can now run GHCi entirely in your browser (if your browser supports WebAssembly and you’re willing to download approximately 220MB of compressed WASM).




I used container2wasm to convert an OCI image containing GHC to a WASM blob that I could serve using a lightly modified container2wasm-demo. If you’re curious, the website repo is here and the chunks of WASM are here.

As of this writing, only images with an uncompressed size below 2GB can be used with container2wasm (tracked here) and my initial attempts using an OCI image generated by Nix were unsuccessful because of duplicate filenames (tracked here).


I’ve wanted to do something like this for a long time. In my capacity as a maintainer of IHaskell, installation issues are the most common category of support request I receive. Wouldn’t it be great if a user could simply navigate to a webpage and have a correctly configured Jupyter notebook waiting for them? The Jupyter folks also seem to be thinking the same thing, based on the existence of JupyterLite. Unfortunately we’re a long way off from Haskell support1, but I hope my proof-of-concept shows that this is possible.

Even outside Jupyter-land, a fully-functional GHCi REPL in the browser would be generally useful. For example, currently has a “Try it!” section where you can enter expressions, which are currently passed to a backend server to execute. A client-side GHCi could provide a better experience and allow us to get rid of the backend entirely. Another wild idea: the Hackage documentation for a package could provide a REPL with that package pre-installed for users to try out immediately. Wouldn’t that be amazing?

Why not compile GHCi directly to JavaScript/WASM using the new backends?

I don’t think that would work/result in a usable Haskell interpreter with access to base or other GHC boot packages. As of this writing it is on the roadmap for GHC 9.12+ so hopefully that will eventually be possible (tracked here). If you get this working I’d love to know about it!

  1. It’s not something I’m working on and I don’t know how to go from this Goldbergian blob of WASM to a kernel that would work with JupyterLite. If you have ideas, please get in touch!↩︎