Teal: A New Option for Bringing Static Types to Lua

Teal is a gradually typed static dialect that compiles to Lua, improving Lua code reliability at low migration cost.
Teal is a statically-typed dialect of Lua. Rather than a new runtime, it is an optional "type layer": developers write Teal code with type annotations, and the tl compiler checks it and generates standard Lua, so it runs in any Lua environment. It follows TypeScript's gradual typing approach relative to JavaScript, allowing developers to start from untyped code and add annotations gradually. Its type system covers basic types, tables, functions, and record types, and supports generics, union types, and type aliases; the toolchain provides type checking, code generation, and .d.tl declaration files, while a community type definition repository further lowers the cost of adding types to existing libraries. Teal is best suited for projects that already use Lua but want stronger type guarantees, such as game logic, configuration, and embedded scripts; scenarios pursuing extreme performance or relying on dynamic features require trade-offs.
Why Do We Need Teal?
Lua is known for being lightweight, embedding-friendly, and dynamically flexible, but the maintenance costs that dynamic typing brings in large projects cannot be ignored. As a statically-typed dialect of Lua, Teal attempts to improve code reliability through compile-time type checking while preserving Lua's runtime semantics.

Teal's Design Philosophy
Teal is not a programming language built from scratch, but rather a "type layer." Its core idea is: developers write Teal code with type annotations, and the tl compiler generates standard Lua code. This means Teal programs can run in any environment that supports Lua, including game engines, embedded systems, and the existing Lua ecosystem.
Similar to how TypeScript relates to JavaScript, Teal allows gradual typing: you can start with untyped code and gradually add type annotations. The type checker catches common errors such as type mismatches and undefined variables, but does not change Lua's runtime behavior.
"Gradual typing" is a formal concept in type theory, referring to allowing some code in the same language to carry type annotations while other code is completely untyped, with safety at the boundary between the two ensured by the type checker automatically inferring or inserting runtime checks. TypeScript, Python's mypy, and Racket's Typed Racket all belong to this category. Its theoretical foundation can be traced back to the gradual type system proposed by Siek and Taha around 2006; the core is introducing "dynamic types" (usually written as ? or any) as a special element in the type lattice, making conversions between them and static types controllable. For Teal, gradual typing means that type annotations are an optional annotation layer; unannotated parts are treated according to Lua's any semantics, so old code can be accepted by the tl compiler in place, and then types can be tightened file by file and function by function without requiring a one-time rewrite.
Type System and Toolchain
Teal's type system covers basic types (number, string, boolean, nil), table types, function types, and optional record types. It supports generics, union types, and type aliases, which is sufficient to express most Lua code patterns.
On the toolchain side, the tl compiler provides type checking and code generation, and can also generate .d.tl declaration files, making it convenient to add type definitions for existing Lua libraries. Editor integration is also being improved, providing developers with completion and jump-to-definition capabilities.
Interestingly, the Teal community maintains a type definition repository covering commonly used Lua libraries, lowering the cost of adoption.
.d.tl declaration files are Teal's mechanism for providing type information for "external Lua code," similar to TypeScript's .d.ts or C header files: they only describe function signatures, field types, and global variables, without containing implementations. This way, a library written purely in Lua needs no rewriting; it only needs to be paired with a .d.tl file, and Teal code calling it will receive type checking and completion hints. Declaration files are usually placed in the same directory with the same name as the library, or explicitly specified using compiler options such as --global-env-def. The community-maintained type definition repository (such as teal-types) covers commonly used libraries like luaossl and luasocket in exactly this form, which is also the key design that enables Teal to integrate into the existing Lua ecosystem at low cost.
Use Cases and Boundaries
Teal is best suited for projects that already use Lua but want stronger type guarantees, such as game logic, configuration systems, and embedded scripts. For scenarios that pursue extreme runtime performance or rely on Lua's dynamic features, Teal's type layer may introduce additional constraints that need to be weighed.
Record types are the core means in Teal for describing Lua table structures, with syntax such as local p: {string:number} or named records local type Point = {x:number, y:number}. They correspond to the Lua idiom of "using tables as structs/objects," and can declare fixed fields, optional fields (adding ? after x:number), and arbitrary key-value mappings. Compared with ordinary table types, record types provide precise checking on field access; misspelled field names or incorrectly assigned types will be reported at compile time. Open records also allow merging with other records via & and relaxing extra fields with .... Understanding record types is key to understanding Teal's type expressiveness, because the vast majority of data structures in the Lua ecosystem are tables.
Summary
Teal plays the role of a "type enhancer" in the Lua ecosystem, making static type checking an optional but powerful tool. For Lua developers struggling with dynamic typing bugs, it provides an improvement path with low migration cost.
One-line Summary
Teal is a gradually typed static dialect that compiles to Lua, improving Lua code reliability at low migration cost.
Paragraph Summary
Teal is a statically-typed dialect of Lua. It is not a new runtime itself, but an optional "type layer": developers write Teal code with type annotations, which is checked by the tl compiler and then generates standard Lua, so it can run in any Lua environment. It borrows the gradual typing approach of TypeScript relative to JavaScript, allowing developers to start from untyped code and add annotations step by step. The type system covers basic types, tables, functions, and record types, and supports generics, union types, and type aliases; the toolchain provides type checking, code generation, and .d.tl declaration files, and the community type definition repository further lowers the cost of adding types to existing libraries. Teal is best suited for projects that already use Lua but want stronger type guarantees, such as game logic, configuration, and embedded scripts; for scenarios pursuing extreme performance or relying on dynamic features, trade-offs are needed.
Related articles

Firebase AI Logic + Gemini Nano 4: A Practical Guide to Android AI Development
How Firebase AI Logic and Gemini Nano 4 help Android developers ship generative AI: App Check and prompt templates ensure security, hybrid routing cuts latency and cost, Spend Caps control budgets, and AI monitoring provides observability.

Microsoft AI Agent Breakthroughs: More Efficient, Better at Code and Weather Forecasting
Microsoft Research Focus Issue 97: ForkPilot cuts agent inference costs, Cabra reveals coding agents' code-understanding gap, Teletune learns workflows from logs, PBC improves extended forecasts, BioEMU-2 opens preview.

Prime Intellect Releases Prime Mega MoE: Trainable Fused MoE Kernel with 3.11x Forward Speedup
Prime Intellect releases Prime Mega MoE, adding backpropagation to DeepSeek's fused Mega MoE kernel for trainability. Up to 3.11x forward speedup and 34% faster Qwen3 MoE training steps in prime-rl.