Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Lux - A typed superset of LuaNew to Visual Studio Code? Get it now.
Lux - A typed superset of Lua

Lux - A typed superset of Lua

DasDarki

|
1 install
| (0) | Free
Language support for Lua Lux — the typed Lua transpiler
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Lux

A typed superset of Lua that transpiles to clean, portable Lua.
Classes, generics, pattern matching, async/await, modules, and a package manager — with zero runtime overhead on the Lua side.

Release Latest release License Issues

Why Lux • Install • Tour • CLI • Packages • Docs • Examples • Contributing


Why Lux?

Lua is small, fast and embeddable — but writing big programs in it hurts: no static types, no module discipline, no class story, no async story. Lux fixes that without leaving Lua:

  • Every valid Lua program is valid Lux — types are optional.
  • The output is idiomatic Lua for any target between 5.1 and 5.4 (plus LuaJIT). No runtime library shipped, no magic at run-time.
  • A full set of modern features are lowered at compile time: classes, generics, interfaces, pattern matching, async/await, doc comments, decorators-via-annotations, an ES-style module system, a strict-nil mode, and an immutability mode.
  • A complete toolchain ships in one binary: compiler, interactive REPL, test runner, native binary bundler, package manager, language server, docs generator.
import { sum, clamp } from "lua-math"

class Counter
    count: number = 0

    function bump(by: number = 1): number
        self.count = self.count + by
        return self.count
    end
end

async function fetch(url: string): string
    return await http.get(url)
end

local c = new Counter()
c:bump()
c:bump(5)
print(c.count)              -- 6
print(clamp(c.count, 0, 5))  -- 5

Lux compiles the above into clean Lua — no runtime library, no helpers you can't read.


Install

One-line install (recommended)

Detects your OS + architecture, pulls the latest release archive, extracts it, and wires lux into your PATH. No admin rights required — everything lands under your user directory.

Linux / macOS (bash / zsh):

curl -fsSL https://raw.githubusercontent.com/LuaLux/lux/master/scripts/install.sh | bash

Linux / macOS (fish — e.g. CachyOS):

curl -fsSL https://raw.githubusercontent.com/LuaLux/lux/master/scripts/install.fish | fish

Windows (PowerShell 5.1+):

irm https://raw.githubusercontent.com/LuaLux/lux/master/scripts/install.ps1 | iex

Open a new shell after the script finishes and lux version should resolve. Pin a specific tag with LUX_VERSION=v0.2.0 (bash / fish) or $env:LUX_VERSION = "v0.2.0" (PowerShell) before running the installer.

Manual install

If you prefer to handle PATH yourself, grab the archive for your platform from the latest release:

Platform Archive
Linux x64 lux-linux-x64.tar.gz
Linux arm64 lux-linux-arm64.tar.gz
macOS x64 lux-osx-x64.tar.gz
macOS arm64 lux-osx-arm64.tar.gz (Apple Silicon)
Windows x64 lux-win-x64.zip
Windows arm64 lux-win-arm64.zip

Each archive contains a single self-contained lux (or lux.exe) binary — no .NET runtime, no Lua runtime required on the target machine. The Lua 5.4 interpreter (via KeraLua), the Lux compiler, and all stdlib type declarations are embedded.

Extract somewhere on your PATH:

# Linux / macOS
tar xzf lux-linux-x64.tar.gz
sudo mv lux /usr/local/bin/
lux version

From source

Requires the .NET 10 SDK.

git clone https://github.com/LuaLux/lux.git
cd lux
dotnet build Lux.sln
./compiler/bin/Debug/net10.0/Lux version

Editor support

The Lux VS Code extension is on the Marketplace. Install it from inside VS Code (Quick Open Ctrl+P / Cmd+P):

ext install DasDarki.lux-lang

Or via the CLI:

code --install-extension DasDarki.lux-lang

Prefer to build from source? The extension lives in vscode-lux/:

cd vscode-lux
npm install && npm run package
code --install-extension lux-*.vsix

The extension launches the bundled lux lps language server — you get hover, go-to-definition, completion, rename, find-references, semantic highlighting, code actions ("Implement interface", "Auto-import"), and signature help out of the box.


Five-minute tour

Scaffold a project

lux init

You get a lux.toml, a src/ folder, and a .gitignore. Drop a src/main.lux:

function greet(name: string): string
    return "Hello, " .. name .. "!"
end

print(greet("Lux"))

Build, run, or just iterate

lux build        # → out/main.lua
lux run          # compile + run via embedded Lua 5.4
lux repl         # interactive prompt (state survives across inputs)

Types are optional, inference does the rest

local x = 42            -- inferred number
local name = "Lux"       -- inferred string
local arr = {1, 2, 3}    -- inferred number[]

function len<T>(xs: T[]): number  -- generics
    return #xs
end

Strict-nil mode kills the billion-dollar mistake

preset = "strict"
local name: string? = maybeName()
print(name:upper())             -- ✗ compile error: name may be nil
print(name!:upper())             -- ✓ explicit non-null assertion
print(name?:upper())             -- ✓ optional chaining: yields nil if name is nil
print((name ?? "anon"):upper())  -- ✓ nil-coalescing

Classes + interfaces

interface Greetable
    function greet(): string
end

abstract class Animal
    name: string
    legs: number = 4

    constructor(name: string)
        self.name = name
    end

    abstract function speak(): string
end

class Cat extends Animal implements Greetable
    constructor(name: string)
        super(name)
    end

    override function speak(): string
        return "meow"
    end

    function greet(): string
        return "hi, I'm " .. self.name
    end
end

Generated Lua uses metatables and setmetatable(self, Class) — no helper library, no shimming.

Pattern matching with exhaustiveness checks

enum Status { Pending, Done, Failed }

local result = match status
    case Status.Pending then "still working"
    case Status.Done then "✓"
    case Status.Failed when retries < 3 then "retrying"
    case _ then "giving up"
end

Type-patterns work too: case x: Dog then x:bark().

Async / await on coroutines

async function load(url: string): string
    return await http.get(url)
end

local body = await load("https://example.com")

Compiles to a coroutine + a __done callback. No external scheduler required — works on every Lua target.

Modules, the ES way

-- math/vec2.lux
export class Vec2
    x: number
    y: number
    constructor(x: number, y: number) self.x, self.y = x, y end
end

-- main.lux
import { Vec2 } from "math/vec2"
import * as utils from "lib/utils"
import "polyfill"            -- side-effect import

local v = new Vec2(1, 2)

Declaration files

Type any existing Lua code without recompiling it. stdlib/std.d.lux ships built-in declarations for print, string, math, table, io, os, etc. Add your own with globals = ["lib/myproject.d.lux"] in lux.toml.

-- redis.d.lux
declare module "redis"
    function connect(host: string, port: number): RedisClient
    interface RedisClient
        function get(key: string): string?
        function set(key: string, value: string): boolean
    end
end

Annotations (compile-time metaprogramming)

@deprecated("use Vec2 instead")
function oldVec(x, y): { x: number, y: number }
    return { x = x, y = y }
end

Annotations are Lux functions that run at compile time and rewrite the IR — powerful enough to implement decorators, lazy initialization, runtime validators, anything you can express by transforming a syntax tree.

Bundle as a standalone binary

lux compile                 # produces ./<project-name> on Linux/macOS
lux compile --out ./myapp   # custom output path

The result is a single self-contained executable: your compiled Lua + KeraLua + all transitive deps from lux_modules/, packed into one file. Ships on a machine that has neither Lua nor .NET.


CLI

Command Description
lux init Scaffold a new project in the current directory
lux create <spec> Scaffold from a git template (e.g. gh:owner/template)
lux build [files...] Compile the project (or specific files) to Lua
lux run [files...] [-- args] Compile and execute via embedded Lua 5.4
lux test [filter] Discover and run unit tests (*_test.lux, tests/)
lux repl Interactive REPL with persistent runtime state
lux compile Bundle the project into a standalone native binary
lux docs [--out dir] Generate documentation site (Markdown + HTML)
lux install Install dependencies into lux_modules/
lux add <spec> Add a runtime dependency (e.g. github:owner/repo@v1)
lux remove <name> Remove a declared dependency
lux registry refresh Refresh the cached alias registry
lux lps Start the LSP language server over stdio
lux version Print the Lux version
lux help Show CLI help

Detailed flags and behavior live in docs/17-cli-reference.md.


Package Manager

Lux ships with a built-in, git-based package manager. Dependencies are declared in lux.toml and installed into a local lux_modules/ directory:

[dependencies]
lux-strings = "github:DasDarki/lux-strings@v1.2.0"
lua-math    = { git = "https://example.com/lua-math.git", tag = "v0.5.0" }
my-utils    = "file:../my-utils"   # local path for development
lux install          # fetch + link everything
lux add github:owner/cool-lib@v1
lux remove cool-lib

The package manager is roundtrip-safe with lux.toml (preserves formatting + comments on lux add/remove), supports lifecycle scripts gated behind --allow-scripts, and resolves transitive dependencies via per-package lux.toml files.

See docs/18-package-manager.md for the full specification.


Project Structure

.
├-- compiler/          Lux compiler + CLI (.NET 10)
│   ├-- Compiler/       Pass pipeline (ResolveLibs → BindDeclare → … → Codegen)
│   ├-- IR/             High-level IR (Node hierarchy, ScopeGraph, SymbolArena, TypeTable)
│   ├-- Configuration/  lux.toml schema
│   ├-- Diagnostics/    Error/warning bag with formatted codes
│   ├-- PackageManager/ Git-based dependency installer
│   ├-- LPS/            Language server (OmniSharp LSP framework)
│   ├-- Doc/            Doc comment parser + markdown/HTML renderer
│   └-- stdlib/         Built-in .d.lux declarations + test framework Lua
├-- runtime/           Embedded Lua 5.4 runtime (KeraLua wrapper, stdlib bindings)
├-- docs/              Language documentation
├-- examples/          Example projects (lux-strings, lua-math, zoo-app)
├-- test/              Runtime test suite (164 tests, all passing)
├-- vscode-lux/        VS Code extension source
└-- assets/            Logo & branding

The compiler and runtime are split: compiler/Lux.csproj produces the lux CLI and references runtime/Lux.Runtime.csproj. The runtime project contains everything a standalone binary produced by lux compile needs — no compiler types.


Architecture

.lux source
    ↓ ANTLR4 lexer + parser
CST
    ↓ IRVisitor (visitor over the parse tree)
HIR (Node tree)
    ↓ Pass pipeline:
    │   ResolveLibs       Load .d.lux declarations + installed packages
    │   ResolveAnnotations  Pre-load annotation plugins
    │   ApplyAnnotations  Run compile-time IR rewrites
    │   BindDeclare       Build scope graph + declare symbols
    │   ResolveImports    Inject imported module ASTs into the package
    │   ResolveNames      Bind every NameRef to its SymID
    │   ResolveTypeRefs   Resolve type annotations to TypIDs
    │   CheckImmutability Enforce const + deep-freeze rules
    │   InferTypes        Propagate types, narrow nilability, check operators
    │   ValidateGenericConstraints
    │   DetectUnused      Mark unreferenced symbols for stripping
    │   DeclGen           Emit .d.lux declarations for the project (optional)
    │   Mangle            Rename for minification (optional)
    │   Codegen           Emit target Lua source
    ↓
.lua output

Each pass declares its scope (per-file or per-build) and dependencies. The PassManager topologically orders them. A separate CheckPipeline (same minus Mangle and Codegen) is used by the language server for fast incremental feedback while you type.


Documentation

Full language reference lives in docs/. Highlights:

  • Getting Started — project setup, lux.toml, target versions
  • Type System — primitives, unions, generics, type aliases
  • Variables & Constants — mutability modifiers
  • Functions — default params, varargs, overloads
  • Control Flow — if/while/for/break N/continue/goto
  • Operators — arithmetic, bitwise, nil-coalescing, optional chaining
  • Classes — inheritance, abstract, protected, static, operator overloading
  • Interfaces — implements, interface inheritance
  • Modules — import/export, declaration modules
  • Pattern Matching — value/type/wildcard patterns, guards
  • Async / Await — coroutine-based async functions
  • Nilability — strict-nil, ??, !, ?.
  • Declaration Files — typing external Lua APIs
  • CLI Reference — every command, every flag
  • Package Manager — dependency specs, install pipeline, registry
  • Annotations — compile-time IR rewrites
  • Doc Comments — LuaCATS-style comments + lux docs
  • Testing — the lux:test framework + lux test
  • REPL — interactive sessions
  • Standalone Binaries — lux compile

Examples

Three runnable projects in examples/:

  • lux-strings/ — a tiny Lux library exposing string utilities (trim, padLeft, startsWith, capitalize).
  • lua-math/ — a pre-built Lua library with typed .d.lux declarations (clamp, lerp, vec2, length2).
  • zoo-app/ — an app that consumes both libraries via the package manager. Demonstrates cross-language imports and standalone binary bundling.
cd examples/zoo-app
lux install      # pulls lux-strings + lua-math
lux run          # → Welcome, Whiskers! …
lux compile      # → ./zoo-app  (standalone)

Roadmap

Current status:

  • ✅ Type system with inference, nilability, generics, exhaustive matching, immutability, operator overloading
  • ✅ Classes, interfaces, abstract, override, protected, static, operator overloading
  • ✅ Pattern matching, async/await, defer/guard, label-free continue, multi-level break
  • ✅ Module system, declaration files, declaration generation
  • ✅ Annotations (compile-time IR rewriting)
  • ✅ Package manager (5 phases: install, toml round-trip, alias registry, auto-discovery, lifecycle scripts)
  • ✅ Doc comments + markdown/HTML doc generation
  • ✅ Embedded Lua 5.4 runtime + lux run
  • ✅ Standard library declarations + stdlib bindings (HTTP, JSON, FS, Console, Project)
  • ✅ Test runner (lux test) with built-in lux:test framework
  • ✅ Standalone binary compiler (lux compile)
  • ✅ Interactive REPL (lux repl)
  • ✅ Language server (hover, go-to-def, completion, rename, references, code actions, sig help, semantic tokens)
  • ⏳ Formatter for consistent code style

Contributing

Issues and pull requests are welcome at github.com/LuaLux/lux. Before opening a PR:

  1. Run the test suite — it must stay at 164/164.
    cd test && lux test
    
  2. Keep generated parser files (compiler/CodeAnalysis/) out of your diff — regenerate via cd compiler && ./gen_antlr4.sh only when you touch the grammar.
  3. Follow the existing style: XML doc comments on public APIs, no comments on obvious code.
  4. New language features should also extend the LSP (compiler/LPS/) so editor support stays consistent.

For substantial changes, please open an issue first to discuss the design.


License

MIT © DasDarki

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft