That said, cranelift is still experimental.
That said, cranelift is still experimental.
Echoing everyone else in this thread that Cranelift might work well for this case; just wanted to add: Cranelift is definitely not "experimental" anymore, though it is still young. It's in production in a number of places (my employer and others) and we test thoroughly, including differential fuzzing against other engines/compilers. It just got a new register allocator, and we even have some academics working on formal verification!
We'd be happy to help with any issues that arise; our Zulip instance (bytecodealliance.zulipchat.com) is probably the best place to find us.
(Disclosure: I work full-time on Cranelift, and have a ton of fun doing it)
If you want a stable interface though, I might use wasm on top of it via wasmtime. I'm not sure how stable the API for wasmtime is, but at least the IR (wasm) is, and there's an ecosystem of tools around it.