Skip to content

Repository files navigation

luainstaller

luainstaller packages a Lua script into a standalone executable that does not require a system lua command at runtime (similar to PyInstaller). The binary runs on the same platform family as the build host.

It supports official Lua 5.1 through 5.5 (LuaJIT is rejected) and is released under LGPL-3.0-or-later at GitHub.

The interpreter used for packaging, the headers, the linked runtime, and any Lua C modules copied into the bundle must share the same major.minor Lua ABI.

A complete official Lua environment and luarocks are required:

luarocks install luainstaller

Confirm with:

luai -v
Note
Lua 5.5 requires LuaRocks 3.13.0 or newer. Older LuaRocks releases do not recognize the 5.5 install ABI.

luainstaller can be used in two ways: as a command-line tool, or as a library from a .lua script.

The CLI has two names: luainstaller and luai. They share the same features (analyze, trace, build, and so on) but use different input syntax and different terminal output. luainstaller is the modern subcommand-style interface; luai is the short-option style closer to traditional Lua tooling. The grammars must not be mixed. Mapping:

Action luai luainstaller

Help

luai -h

luainstaller help

Version

luai -v

luainstaller version

Analyze

luai -a <entry>

luainstaller analyze <entry>

Trace

luai -t <entry>

luainstaller trace <entry>

Build

luai -b <entry>

luainstaller build <entry>

Logs

luainstaller logs

Unless noted otherwise, command-line examples use luai. Details: Usage.

Suggested order: confirm the source program runs → analyze/trace dependencies → build a directory bundle (onedir) → run with LUA_PATH and LUA_CPATH cleared → then build a single-file (onefile) if needed. The directory form exposes the manifest, generated C, and native libraries; onefile is self-extracting—if it fails, verify the matching directory bundle first.

Example:

lua test/runtime_bundle/main.lua direct
luai -a test/runtime_bundle/main.lua --max-deps 120
luai -t test/runtime_bundle/main.lua --max-deps 120
luai -b --dir test/runtime_bundle/main.lua \
  -o build/runtime-demo --max-deps 120
build/runtime-demo/runtime-demo Ada

After the directory bundle works:

luai -b --file test/runtime_bundle/main.lua \
  -o build/runtime-demo-onefile --max-deps 120
build/runtime-demo-onefile Ada

Expected output begins with hello Ada.

Common luai options:

  • --dir — directory bundle (default)

  • --file — single-file executable

  • -o — output path

  • --max-deps — limit on auto-discovered Lua dependencies (default is small; raise it for large apps)

  • -d static|runtime|manual — discovery mode (default static)

Before release, run the artifact at least once without a system lua and without LUA_PATH / LUA_CPATH, so missing dependencies are not hidden by the host. Platform limits: Platforms and native modules. Diagnosis: Troubleshooting.

Every generated distribution contains the Lua MIT notice, the luainstaller LGPL/GPL texts, third-party notices, generated C source, and relinking instructions. Preserve them when redistributing an artifact and add the notices/source required by application dependencies. Details: Relinking generated bundles.

After install, require("luainstaller") uses the same implementation as the CLI. The structured result contract applies to analyze, trace, compatibility, and bundle only. Success sets ok = true; failure sets ok = false and error (with type, message, and related fields). getLogs returns a list of log records; clearLogs returns a boolean. Version string: require("luainstaller").VERSION.

local luainstaller = require("luainstaller")

local analysis = luainstaller.analyze({
    entry = "app/main.lua",
    discovery_mode = "static",
    max_deps = 120,
})
if not analysis.ok then
    io.stderr:write(analysis.error.type, ": ", analysis.error.message, "\n")
    os.exit(1)
end

local built = luainstaller.bundle({
    entry = "app/main.lua",
    mode = "onedir",
    out = "build/app",
    max_deps = 120,
})
if not built.ok then
    io.stderr:write(built.error.type, ": ", built.error.message, "\n")
    os.exit(1)
end
print(built.executable)

Option meaning matches the CLI. Full API notes are in Usage.

v1.3 selects implementations by native capability rather than by a short OS allowlist. Builds remain native: the compiler, Lua headers/library, native modules, architecture and target OS must agree. The release gates and platform-specific contract cover:

System Architecture Compatibility path

Windows XP SP3 / XP x64 SP2 or newer

x86 / x86_64

XP API baseline and onefile watchdog fallback; XP-capable CRT and Lua DLL

Modern Windows

x86, x86_64, ARM, ARM64

Native MSVC/MinGW linker-machine selection

Linux

x86 and x86_64

32/64-bit userland detection; shared or static Lua

Linux

ARM and ARM64

Shared or static Lua

Android / Termux

native Termux architecture

App-private prefix, Bionic ABI and Termux temporary root

FreeBSD

native architecture

libc dlopen, sysctl executable path, shared or static Lua

macOS

x86_64 and ARM64

Static Lua preferred; verified dylib fallback

Windows XP builds require PowerShell 2 or newer and an XP-targeting compiler runtime; installing a modern compiler on a new host does not by itself make its CRT XP-compatible. Full requirements and evidence tiers: Platforms and native modules and Testing.