English | 한국어
All notable changes to this project are documented here. The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
While the version is 0.x, the public API may change between minor releases.
- Bump the
lua-puredependency to v0.1.2 and, to satisfy its toolchain requirement, raise the minimum Go version to 1.25 (go.modnow pinsgo 1.25.11; was1.24).
0.0.1 - 2026-07-05
Initial public release of luart — a high-performance, concurrency-safe
runtime for running Lua scripts in Go, built on
lua-pure (a pure-Go PUC-Lua 5.4 port).
Requires Go 1.24+. The core library depends only on lua-pure; the config loader's
YAML dependency is isolated in the luartconfig subpackage.
New(loader SourceLoader, cfg Config) *Runtime— a lazy-loading, pooling runtime with a background janitor.Run(ctx, key, entryFn, args…) ([]lua.Value, error)— compile once perkey:version, then reuse a preloaded State from the per-script pool.RunWith(ctx, key, entryFn, handle, args…)— consume results while the State is still owned (any return type safe to read/call insidehandle).RunValues(...) ([]any, error)— deep-copy results to Go values for use after the call; non-data values go through theConfig.ConvertValuehook.- Lifecycle:
Close()(immediate) andShutdown(ctx)(graceful drain).
- Per-
key:versionbytecode cache (CompileCache): a script is parsed and compiled only on first use; later runs are cache hits (effectively 0-alloc, size-independent). - Per-script pool of Lua States, reused across calls. States are never shared across goroutines — the single-owner invariant holds under load.
- Lazy load on first
Run; TTL idle eviction (IdleTTL/JanitorInterval). - Memory-budget-derived
MaxStates(MemoryBudgetBytes ÷ measured per-State cost) with global idle-LRU eviction and FIFO back-pressure at the cap (arrival-ordered, context-aware — no lost wakeups or polling). - Notification-driven hot reload:
Notify(key, version, displayVersion)/NotifyChanges([]Change)drop a pool; the nextRunreloads it. In-flight States finish on the old version, then are discarded.
SourceLoaderinterface +MapLoader(in-memory),HashVersion(src)(content-hash versioning). Example File / DB / Memory / caching / routing loaders inexamples/custom-loaders(seedocs/SourceLoader.md).luartconfigsubpackage:LoadJSON/LoadYAML/Load(by extension) /FromEnv, plusResolve(precedence env > file/string > defaults) andConfig.Validate().
Config.ExecTimeout— per-execution wall-clock cap; a cancelablectxpassed toRunis honored too (0= disabled, zero overhead; pure-Lua loops).Config.MaxInstructions— per-Runopcode cap for runaway pure-Lua CPU, orthogonal toExecTimeout; exceeding it returnsErrInstructionLimit.Config.IsolateGlobals— run eachRununder a fresh_ENVso a script's global writes don't leak into the next call reusing the same pooled State.- Pooled States run in protected mode: a panicking Go callback is recovered into a catchable error and the State is unwound to a reusable state.
- Default library set is lua-pure's safe Lua 5.4 subset
(
base/table/string/math/utf8/coroutine;load/loadfile/dofileremoved; noos/io/package/debug). SkipOpenLibsopens nothing by default;Config.Libsselects exactly what opens;Config.ExtraLibsadds custom libraries (Go functions, module tables,L.Preloadlazyrequire) after the sandbox defaults.
Metricsinterface (no-op default),Loggerinterface +NewSlogLogger, per-stageTraceHook. Snapshots viaStats(),PoolStats(),CompileCount().
Makefileas the single source of truth (make all= vet → test → race → build); GitHub Actions CI mirrors it.examples/(one folder per public feature),cmd/technique demos, andperformance/(a lua-pure vs PUC-Lua compile-cost comparison).- README (en/ko),
docs/config.md,docs/tuning.md,docs/SourceLoader.md(each with a Korean.ko.md).