rainsi-lua
v1.1.0
Published
Multi-version Lua & Luau Virtual Machine in WebAssembly/WASI (Lua 5.1.5 - 5.5.1 and Luau 0.739) with seamless bidirectional type-marshalling, JS function registration, and sandbox security.
Maintainers
Readme
rainsi-lua
A robust, zero-dependency, multi-version Lua & Luau Virtual Machine for WebAssembly and WASI. Run standard Lua and modern Luau code directly in any browser or Node.js environment with high performance.
🚀 What's New in v1.1.0: Luau 0.739 Support!
rainsi-lua now includes first-class support for Luau 0.739 (Roblox's fast, type-safe, embeddable Lua derivative):
- ✨ Gradual & Static Type Checking Annotations:
type Point = { x: number, y: number } - ⚡ Modern Language Ergonomics:
- Compound assignment operators (
+=,-=,*=,/=,%=,^=,..=) continuestatements infor,while, andrepeatloops- String interpolation literals (e.g.,
`Hello ${player.name}!`) - If-then-else expressions (
local x = if condition then a else b)
- Compound assignment operators (
- 📦 Luau Standard Libraries:
bufferlibrary for high-speed binary data manipulation (buffer.create,buffer.writeu8,buffer.readstring, etc.)bit32,utf8,table,string,math,coroutine, and vector types
- 🔒 Full WASI Sandbox & JS Trampoline: Run untrusted Luau scripts safely with stdio interception, virtual filesystem, and bidirectional JavaScript bindings.
Supported Versions
| Version | Engine | WASM Size | Highlights |
| :--- | :--- | :--- | :--- |
| 0.739 | Luau | ~1.3 MB | Types, compound operators, string interpolation, buffers, vectors |
| 5.5.1 | Standard Lua | ~664 KB | Latest standard Lua release build |
| 5.4.7 | Standard Lua | ~678 KB | Generational GC, <const> / <close> variables, integers |
| 5.3.6 | Standard Lua | ~634 KB | Native 64-bit integers, bitwise operators, UTF-8 library |
| 5.2.4 | Standard Lua | ~617 KB | _ENV lexical scoping, goto, bit32 library |
| 5.1.5 | Standard Lua | ~609 KB | Classic Lua 5.1 legacy runtime and compatibility |
Installation
npm install rainsi-luaQuick Start
1. Running Luau 0.739 with Modern Syntax & Types
import { LuaEngine } from 'rainsi-lua';
// Initialize the Luau 0.739 runtime
const luau = await LuaEngine.create({ version: '0.739' });
// Register a JS callback
luau.register('onScore', (msg: string, score: number) => {
console.log(`[JS Event] ${msg} -> Score: ${score}`);
});
// Run Luau code using type annotations, compound operators & string interpolation
const result = luau.run(`
type Player = { name: string, health: number }
local p: Player = { name = "Hero", health = 100 }
p.health += 25
local bonus = 500
bonus *= 2
local message = \`\${p.name} earned \${bonus} XP (HP: \${p.health})\`
print(message)
onScore(message, bonus)
return { player = p, xp = bonus, summary = message }
`);
console.log(result.values[0]);
// Output: { player: { name: 'Hero', health: 125 }, xp: 1000, summary: 'Hero earned 1000 XP (HP: 125)' }
luau.close();2. Running Standard Lua (5.1 – 5.5)
import { LuaEngine } from 'rainsi-lua';
const lua = await LuaEngine.create({ version: '5.4.7' });
const result = lua.run(`
local sum = 0
for i = 1, 10 do
sum = sum + i
end
return sum, _VERSION
`);
console.log(result);
// Output: { ok: true, values: [55, "Lua 5.4"] }
lua.close();API Reference
LuaEngine.create(options)
Asynchronously instantiates the WebAssembly-backed Lua or Luau state.
const engine = await LuaEngine.create({
version: '0.739', // '0.739' | '5.5.1' | '5.4.7' | '5.3.6' | '5.2.4' | '5.1.5'
wasmBase: '/wasm/', // Optional custom base URL/CDN path for .wasm files
wasmSource: wasmBytes, // Optional ArrayBuffer / Uint8Array binary override
args: ['main.lua', 'arg1'],// Populated into Lua's global 'arg' table
onStdout: (text) => {}, // Intercept standard output stream (print, io.write)
onStderr: (text) => {}, // Intercept standard error stream
});engine.run(code)
Executes code and returns { ok: true, values: any[] } or { ok: false, error: string }.
engine.doString(code)
Executes code and returns the primary return value directly, throwing on error.
engine.runWithMetrics(code)
Executes code and returns execution duration in milliseconds along with stdout/stderr buffers and return values:
const { ok, result, executionTimeMs, stdout, stderr } = engine.runWithMetrics(`
print("Calculating...")
return math.sqrt(144)
`);engine.set(name, value) / engine.get(name)
Get and set global variables with automatic bidirectional type conversion (primitives, arrays, and nested tables).
engine.register(name, fn)
Exposes a JavaScript function to the Lua global environment so Lua scripts can call it synchronously or asynchronously.
engine.close()
Frees WASM memory allocations and destroys the Lua state instance.
License
MIT License.
