Typed Lua source-to-source tooling for LuaJIT and LOVE projects.
Documentation · GitHub Releases · VS Code Extension
Tua starts with normal Lua syntax, adds erased type syntax and a small amount of LuaJIT-safe sugar, then emits readable Lua 5.1-compatible code. It is built for projects that want stronger editor feedback, static checks, and build tooling without leaving the normal Lua and LOVE workflow.
local controls = input({
controls = {
left = { "key:left", "key:a" },
right = { "key:right", "key:d" },
up = { "key:up", "key:w" },
down = { "key:down", "key:s" },
collect = { "key:space", "button:a" },
pause = { "key:escape", "button:start" },
},
pairs = {
move = { "left", "right", "up", "down" },
},
})
local game = store({
score = 0,
player = vec2(80, 120),
})
local flow = stateMachine({
initial = "playing",
events = {
{ name = "pause", from = "playing", to = "paused" },
{ name = "resume", from = "paused", to = "playing" },
},
})
local events = signal()
events:on("coin.collected", function(points: number)
game:update(function(state)
state.score += points
end)
end)
function love.update(dt: number)
controls:update()
if controls:pressed("pause") then
if flow.current == "playing" then flow:pause() else flow:resume() end
end
if flow.current ~= "playing" then return end
local moveX, moveY = controls:get("move")
game:update(function(state)
state.player.x += moveX * 180 * dt
state.player.y += moveY * 180 * dt
end)
if controls:pressed("collect") then
events:emit("coin.collected", 10)
end
end
function love.draw()
local state = game:get()
love.graphics.circle("fill", state.player.x, state.player.y, 16)
love.graphics.print("Score: " .. tostring(state.score), 16, 16)
endThis repository contains the compiler core, CLI, language server, VS Code extension, documentation site, and bundled example projects.
- Erased local, function, alias, table-shape, optional-field, and union types.
- Readable Lua 5.1-compatible output for LuaJIT and LOVE 11.x.
- A CLI for
init,check,fmt,lint,build,traceback,watch, andlsp. - A compiler-backed language server and VS Code extension with diagnostics, completion, hover, signature help, rename, references, semantic tokens, inlay hints, document/workspace symbols, and more.
- LOVE-aware helpers, API catalogs, callback guidance, and asset-path validation for both Tua helpers and native LOVE constructors.
- Opt-in built-in helpers such as
Vec2,spriteSheet({...}), Baton-backed typed input, signal buses, state stores, state machines, ECS, and object pools. - Mixed-source builds where
.tuafiles compile to.lua, while plain.luafiles and assets are copied into the build output for runnable LOVE folders.
- Write typed gameplay code that still ships as ordinary Lua source.
- Keep existing Lua modules and gradually adopt
.tuawhere stronger tooling helps. - Build LOVE projects with editor-aware assets, generated-Lua/source-map navigation, source-mapped Lua debugging, and project graphs for modules, signals, state machines, ECS, and object pools.
- Use one versioned toolchain across the CLI, language server, release VSIXs, and documentation.
The extension lives in editors/vscode and is distributed through GitHub
release VSIXs plus registry publishing for Visual Studio Marketplace and Open
VSX. Published VSIX packages bundle the matching tua server binary for each
platform, so extension installs do not download a server at activation time.
It provides compiler-backed Tua editing, LOVE-aware completion and diagnostics, generated Lua inspection, project commands for running or debugging LOVE, and source-linked explorers for assets, modules, signals, state machines, ECS, and object pools.
Experimental local Ollama ghost-text completion is opt-in and compiler
validated before display. Trusted local tools can also explicitly start the
read-only tua api --stdio JSON-RPC session or tua mcp --stdio; neither
service opens a network socket or starts automatically.
- Documentation site
- Installation
- Quickstart
- Language overview
- Typed state machines
- Typed state stores
- Typed input
- CLI reference
- Language server
- External API and MCP
- Debugging
- Examples
- Releases and compatibility
- CHANGELOG.md
Pending contributor priorities are tracked in ROADMAP.md.
cargo test --workspace
cargo run -p tua-cli -- --helpUseful local workflows:
make build-features
make editor-regression-smoke
make extension-packageGitHub Linguist support materials live in support/github-linguist/.
Serve the documentation site locally:
make docsexamples/featuresis a buildable tour of the v1 language and LSP features.examples/linterintentionally breaks every currently emitted standard lint rule and is expected to failtua lint.examples/love-minimalis a small LÖVE smoke-test project.examples/love-fullis a larger LÖVE conversion example with Lua interop.examples/love-tuais a mixed Tua/Lua bullet-hell showcase combining ECS, object pools, stores, state machines, typed input, and vendored Feel feedback.