#+title Compile ClojureScript to WebAssmebly using cherry and javy #+author Eugen Stan
This is a demo repo to try and compile ClojureScript to WASM using javy.
Once we have the wasm file we can try to run it using one of the existing runtimes. I imagine we will need a runtime that supports GC - such as Chrome / Firefox or Node.js . See https://webassembly.org/features/ for un up to date list.
You will need node.js for cherry and javy binary locally.
You can follow the guide for cherry here: https://github.com/squint-cljs/cherry and for javy here: https://github.com/bytecodealliance/javy .
I have created the example files in this repo to use as a boilerplate.
The code is very bare-bones - just the example from cherry site.
It works. I did not try anything more than this.
The final wasm is quite big at ~6.8MB . Removing cherry require’s (which are needed only for evaluating clojurescript in WebAssmebly) gets the generated wasm to ~2MB. Still large but I’m happy with this.
(ns my.cherry
(:require [cherry.embed :as cherry]))
(cherry/preserve-ns 'cljs.core)
(cherry/preserve-ns 'clojure.string)
(defn add [a b]
(+ a b))
(defn init []
(println "Hello from init!" (add 1 3)))
(println "Hello world!" (add 1 4))
# compile ClojureScript via shadowclj to embed cherry.core and produce a single js file
clojure -M:cherry:shadow release cherry-wasm
# compile js to wasm
javy compile out/js/cherry-wasm.js -o cherry.wasm
# Run my-cherry.wasm using wasmtime
wasmtime cherry.wasm
Hello world! 5
Hello from init!
# Run it with node.js (output redacted for brevity)
node --experimental-wasi-unstable-preview1 node-run-cherry-wasm.cjs
Hello world! 5
Hello from init! 4
Javy currently exposes a limited API for interacting with the outside world. Only stdin and stdout are allowed. See Invoking Javy-generated modules programatically I created an issue to see if we can also get command line arguments and environment variables.