Are you an LLM? You can read better optimized documentation at /adrs/0001-use-luau-as-the-embedded-language.md for this page in Markdown format
0001. Use Luau as the embedded scripting language
Date: 2026-05-03
Status
Accepted
Context
neoc needs an embedded scripting language for user-supplied scripts running inside the host runtime. The language must run in a host that controls the execution environment tightly, must permit fine-grained sandboxing of the operating-system surface exposed to scripts, and must not require the host to ship a JIT or a full ECMAScript runtime.
Several candidates were available:
- Lua 5.4 — small, well-documented, widely embedded. Has the standard library that
os,io,package, anddebugmodules expose, much of which is unsafe in a multi-tenant runtime and would need to be stripped. - Luau — Roblox's dialect of Lua. Sandbox-aware by design (the language explicitly drops or restricts unsafe surface), gradual typing, deterministic execution. Implemented in C++ and bindable from Rust through the
mluacrate'sluaufeature. - JavaScript via Deno or Boa — large surface, heavyweight runtime, less amenable to embedding into a fixed-resource host.
- WebAssembly — capable, but the source-language story is downstream and the tooling burden on script authors is high.
- Custom DSL — too narrow; user scripts need general-purpose expressivity.
The host runtime is written in Rust. The bindings story for the embedded language is a load-bearing concern; the choice must integrate cleanly with mlua or an equivalent.
Decision
neoc uses Luau as its embedded scripting language. The Luau interpreter is bundled into the binary through mlua's vendored feature.
Consequences
- Scripts benefit from Luau's gradual type system and its sandbox-aware design. The language itself drops parts of the Lua standard library that are unsafe for embedding (notably
dofile,loadfile, and parts ofpackage), reducing the surface that must be stripped at the host level. - The host runtime can rely on Luau's deterministic execution semantics — no JIT, predictable allocation behaviour — when reasoning about embedded scripts.
- Script authors must use Luau syntax and semantics rather than vanilla Lua. Most Lua libraries written for 5.1/5.4 are compatible with adaptation; a small number that depend on stripped surface or on Lua-specific features (such as integer/number distinction) require porting.
- The choice of
mluaas the binding layer gates this decision on the upstream maintainer's continued Luau support. Migration to a different binding layer would be possible but would require non-trivial work. - The
mluavendoredfeature bundles Luau into the neoc binary, so the host does not depend on a system Lua installation. This simplifies distribution at the cost of a larger binary.