Lua 5.1–5.5,
written in Rust.
omniLua is a Lua interpreter written in Rust. It runs Lua 5.1 through 5.5 on the command line, embedded in your code, or in the browser. No C dependency.
It passes the official PUC-Rio test suite and runs the stock LuaRocks client.
$ omnilua -e 'print(6 * 7)'
use omnilua::Lua; let lua = Lua::new(); lua.load("print(6 * 7)").exec()?;
import { loadLuaRs, luaRsWasmUrl } from "omnilua"; const { lua } = await loadLuaRs(luaRsWasmUrl); lua.exec("print(6 * 7)");
import { loadLuaRsNode } from "omnilua/node"; const { lua } = await loadLuaRsNode(); lua.exec("print(6 * 7)");
Try it — one snippet, five Luas
edit the code and run it live on every version; the output divergeslive — your code on each version's backend ref — reference output, shown until the runtime loads
Why omniLua
omniLua is written in Rust, so the same build runs natively and compiles to WebAssembly. mlua and rlua are C-backed and can't run in the browser. That, plus five Lua versions from one build and a sandbox for untrusted scripts, is the reason to pick it.
| omniLua | mlua | |
|---|---|---|
| Pure Rust, no C | yes | no |
| Runs in the browser (wasm) | yes | no |
| Lua versions | 5.1–5.5 | one per build |
| Sandbox for untrusted scripts | yes | Luau only |
| LuaJIT speed | no | yes |
Use mlua if you need LuaJIT speed or a mature C binding. Use omniLua for the browser, multiple versions, or a sandbox.
What you can build
Game scripting
Script your game in Lua and keep that scripting when the game ships to the browser. The repo has a Bevy example that drives an entity from Lua each frame and builds to wasm.
Untrusted scripts
Run user-supplied scripts in a sandbox with hard CPU and memory limits and the standard library removed. The limits can't be caught from Lua and refill per run.
Lua everywhere
One build runs as a command-line interpreter, an embedded Rust library, and an npm package for the browser or Node. All five Lua versions come from the same core.
Proof
./harness/run_official_all.sh.inspect, dkjson, and argparse.unsafe outside the garbage collector, the dynamic-library loader, and the wasm ABI.| Version | Tested against |
|---|---|
| 5.4 | The full official PUC-Rio suite |
| 5.3 / 5.5 | Their own upstream test suites |
| 5.1 / 5.2 | The reference lua binary |
This is Lua source compatibility, not C API/ABI compatibility. 5.1 and 5.2 have no integer type, and math.random uses a Rust PRNG, so its sequence differs from C.
Performance
Competitive with reference C, tracked per commit. It's an interpreter, not a JIT.
vs reference C
2.4× faster than C
bounds checks + guards
Get omniLua
$ cargo install omnilua-cli
# Cargo.toml
omnilua = "0.4"
$ npm install omnilua
use omnilua::Lua; let lua = Lua::new(); let f = lua.create_function(|_, name: String| Ok(format!("hello, {name}")))?; lua.globals().set("greet", f)?; lua.load(r#"print(greet("omniLua"))"#).exec()?; // → hello, omniLua
Full API on docs.rs · the browser/Node package wrapper, with a runnable example, on npm.