[ANN] (Experimental) WasmTarget.jl & Therapy.jl: Julia-to-WebAssembly compiler, with a full-stack signals framework built on it

have you tried to compile JuMP.jl by any chance yet?

No not yet but I will add JuMP to the list too!

Thanks! I am very curious if I can replicate my CVXPY wasm demo here Home Energy Management with CVXPY + HiGHS in the Browser | De Vonk :smiley:

JuMP works as an interface, and I generally use HiGHS, Ipopt, and GLPK as backend solvers. How should I plan to make my workflow work seamlessly in browsers with these JLL-based optimizers? As far as I know, the number of pure-Julia optimizers compatible with JuMP is currently quite limited.

I’m not sure yet, but for the next week or two (my best guess) I’ll be focused on getting the current version of WasmTarget.jl closer to structural parity with dart2wasm. Claude Code drifted into a lot of ad-hoc implementations inside the compiler, and I want to shore those up into something more principled and uniform. Once that lands, I’ll move back to library integration testing, and I’ll make sure JuMP is part of that round. I’m not optimistic the JLLs will just work, though, since ccalls are still tough for the compiler to handle.

There are many packages in Julia that use JLLs. It seems we are heading toward a crossroads for these types of packages:

  1. Rewriting what the JLL does in JavaScript

  2. Rewriting what the JLL does in Julia and getting rid of ccalls

  3. Compiling the source code of the JLL separately into a Wasm target and adding it to our project’s imports list

The first choice isn’t even feasible for most tasks. While the second is possible, it’s often impractical. Looking at the third option, it seems more likely because the most practical approach is to compile the underlying Fortran, C, C++, or Rust code of all JLLs into WASM and use that compiled WASM code in the project’s imports list. For this, a platform to store the WASM counterparts of the JLLs will be needed, as this workflow is not achievable for everyone.

As humanity, we waste too much energy creating new technologies from scratch only to port everything over to them later.

I agree with Option 3. This is how dart2wasm works I am pretty sure: it doesn’t compile the native code itself. Instead, it imports the “pre-compiled” native code and auto-generates the “glue” needed to connect them.

If understand it correctly, the real challenge is the memory barrier. Our Julia => wasm compiler uses garbage-collected memory (wasm-GC), but native libraries (JLLs) use linear memory.

But since dart2wasm does exactly this, then I think we can take their ideas and hopefully integrate JLLs and things somewhat seamlessly later on following their lead

Ok, I burned quite a few tokens to push the implementation to actually compile a real Julia solver! :smiley:
I started fixing lots of things in WasmTarget, but abandoned that effort at some point, since it was going in circles fixing corner cases in the Julia IR, and also not having linear memory really annoyed me, so I went back to my Whisk.jl prototype, which starts from LLVM IR (which is more stable) and tries to compile parts of the julia runtime to wasm, to have a real gc on linear memory…

Its still a mess, but I managed to compile Tulip.jl for solving @langestefan hem example:
image

Hope it’s similar enough to be relevant, and not generating completely wrong outputs :smiley: I did test it against the original julia output, but I’m not sure if the whole solver etc is setup correctly.
Will publish more once i found time to clean up the implementation

Ooh so does Whisk.jl allow for more ccall-ed julia functions then?

Not quite, it is another Julia-to-WASM implementation, done at a different level. WasmTarget compiles Julia typed IR, Whisk compiles typed CodeInfo/IRCode (one level lower)