Nesta página
Introdução — O que é Zolo, e por que ela existe
Zolo — Lua moderna, 2026.
Zolo é a linguagem tipada e ergonômica do ecossistema Lua. Ela compila pra Lua 5.1 bytecode puro (sem runtime extra) e também tem path nativo (Cranelift) e WASM. É o momento TypeScript do Lua.
Esta página existe pra explicar por que a linguagem existe antes de ensinar sintaxe. Se você quer ir direto pro código, vá pra Getting Started.
O vácuo no ecossistema Lua¶
Lua é uma das linguagens de verdade mais usadas do mundo — e quase ninguém fala disso porque ela vive escondida dentro de outras coisas:
- Roblox / Luau — ~100M de usuários ativos, milhões de scripters.
- Neovim — toda a configuração e plugin system.
- Redis — scripts atômicos via
EVAL. - Garry's Mod, World of Warships, Don't Starve, Factorio, Stormworks — gameplay e modding.
- OpenResty / Kong / HAProxy — edge computing, gateways, filtros.
- Wireshark — dissectors.
- Embedded — qualquer coisa que precisa de scripting com runtime de 200KB.
Em todos esses lugares, a alternativa é Lua puro. E Lua puro é doloroso quando você quer escrever algo sério:
- Sem tipos — o bug aparece em produção, não no editor.
- Sem
match, sem traits, sem enums com payload. - Escopo confuso:
localem todo lugar, ou esquece e vira global. - 1-indexado (todo mundo já tropeçou nisso).
- Tooling pobre — autocomplete genérico, debugger limitado.
requireé umdofileglorificado, sem sistema real de módulos tipados.
Tentativas de melhorar isso existem:
- Teal e Luau adicionam tipos a Lua, mas conservadoramente — Lua + anotações.
- MoonScript está morto.
- Fennel é Lisp, ótimo, mas público nicho.
- Haxe compila pra Lua mas é uma linguagem de propósito geral, não pensada pro ecossistema Lua.
Ninguém ocupou o lugar de "o TypeScript do Lua" — uma linguagem moderna, com pattern matching, traits, generics, decorators, tooling de primeira classe, que compila pra Lua bytecode e roda drop-in em qualquer host Lua.
Esse é o vácuo que Zolo ocupa.
Os 6 pilares¶
1. Tipada por padrão, gradual quando útil¶
Tipos são a coisa principal. Mas você não precisa anotar tudo o tempo todo.
let mut x = 0 // infere int
let mut name = "Alice" // infere str
let users: [User] = [] // anotação quando precisa
fn greet(u: User) -> str {
return "Hello, {u.name}"
}Quer escapar do sistema de tipos? Existe any — mas ele dá warning sem #[allow_any]. A linguagem não te impede de ser dinâmico; ela só te avisa que você está sendo.
2. Compila pra Lua bytecode 5.1 puro, sem runtime¶
Esse é o killer feature. Zolo emite Lua 5.1 que roda em qualquer host Lua compatível, sem patch, sem hook, sem runtime extra.
zolo compile script.zolo > script.lua
# script.lua roda em Roblox, Neovim, Redis, GMod, OpenResty, Wireshark...Você escreve um plugin Neovim em Zolo. Você escreve um script Roblox em Zolo. Você escreve um filtro OpenResty em Zolo. Mesma linguagem, mesmas ferramentas.
// Mesmo código que vai rodar dentro do Neovim como plugin
struct Buffer {
id: int,
name: str,
}
fn current_buffer() -> Buffer? {
let id = vim.api.nvim_get_current_buf()
if id == 0 { return nil }
return Buffer { id, name: vim.api.nvim_buf_get_name(id) }
}3. Path nativo (Cranelift) e WASM, com paridade¶
Quando não há host Lua — você quer um CLI, um daemon, um binário standalone — Zolo também compila pra:
- Native via Cranelift (binário Linux/macOS/Windows).
- WASM (browser, edge runtimes, plugins WASI), com path de runtime e um path ahead-of-time (AOT) emergente.
A semântica é a mesma. Você escolhe o alvo na hora de compilar.
zolo build --target lua # Lua 5.1 bytecode (default)
zolo build --target native # binário nativo
zolo build --target wasm # WebAssemblyHonestidade: a VM Lua 5.1 embarcada (NaN-boxing, tri-color GC, 38 opcodes) é cerca de 5x mais lenta que LuaJIT. Performance é foco de roadmap, não de hoje. O foco atual é ergonomia + portabilidade. Se você precisa de hot-loops a velocidade de C, use o backend native, ou rode o Lua emitido sob LuaJIT.
4. Tooling de primeira classe desde o dia 1¶
Não tem "vamos adicionar LSP depois". O Language Server já cobre go-to-definition, references, rename, inlay hints, semantic tokens, code actions, diagnostics, call hierarchy e mais. Tudo isso existe desde o início:
zolo-lsp— Language Server completo.zolo-fmt— formatter.- DAP — debugger adapter protocol, breakpoints, step, watch.
zolo repl— REPL.- VS Code extension em
editors/vscode/. - Hot-reload em desenvolvimento.
Tudo isso antes de 1.0 — porque editor sem ferramenta é a primeira dor de quem vem de TypeScript ou Rust.
5. Plugins idiomáticos, não FFI cru¶
Plugins do Zolo são cdylib em Rust, mas a interface que você usa não vaza Rust. Quem usa não percebe.
use http
let res = http.get("https://api.example.com/users")
let users = res.json() as [User]
for u in users {
print(u.name)
}Sem ffi.cdef, sem casts manuais, sem leak de detalhes do binding. Os plugins têm tipos, autocomplete, hover.
Hoje há 180+ plugins implementados como cdylibs Rust (crypto, json, http, datetime, image, http-server e muitos outros). Veja PLUGIN_ROADMAP.md.
6. Honestidade sobre custos¶
Zolo não promete "zero cost". Toda alocação que acontece é, na medida do possível, sinalizada via lint:
- "Esta operação aloca uma nova table."
- "Este
matchem string é O(n) — considere umenum." - "Você está usando
anyaqui — perde checagem estática."
Você decide se aceita o custo. Mas você sabe. Não há mágica escondida.
Onde Zolo brilha¶
- Plugins Neovim com tipos de verdade, sem precisar virar gigante.
- Scripts Roblox/Luau modernos, com pattern matching e traits.
- Edge functions OpenResty/Kong com sintaxe decente.
- Modding de jogos que usam Lua (GMod, World of Warships, indie games).
- Scripts Redis complexos com checagem estática.
- Creative coding e game scripting (subnicho compatível — vibe-coder, plugins wgpu/winit/rapier).
- CLI / daemons standalone via backend nativo, quando não há host.
Onde Zolo não é a melhor escolha¶
Honestidade primeiro:
- Systems programming (kernel, drivers, runtimes). Use Rust ou Zig.
- Hot path numérico sem alvo LuaJIT e sem alvo native. A VM Lua 5.1 padrão é lenta.
- GC determinístico (tempo real duro, áudio em sample-level). Use Rust.
- Apps mobile nativas com SDK próprio (Swift/Kotlin). Zolo não tem binding pra UIKit/Android.
- Ecossistema gigante de libs já existentes como Python/Node tem hoje. Zolo está em pre-1.0.
Zolo não é um substituto de Rust, Swift ou TypeScript em geral. É um upgrade do Lua — e ela é boa exatamente onde Lua já é a escolha certa.
Mini-exemplo end-to-end¶
use std::Array
// users.zolo
struct User {
name: str,
age: int,
email: str?, // optional
}
trait Greetable {
fn greet(self) -> str
}
impl Greetable for User {
fn greet(self) -> str {
return match self.age {
a if a < 18 => "Hi kid {self.name}",
_ => "Hi {self.name}",
}
}
}
fn fetch_users() -> [User] {
return [
User { name: "Alice", age: 30, email: "alice@x.com" },
User { name: "Bob", age: 12, email: nil },
]
}
fn main() {
let users = fetch_users()
users
|> Array.filter(|u| u.age >= 18)
|> Array.map(|u| u.greet())
|> Array.each(print)
// First-class temporal literals
every 5s {
print("heartbeat from {users.len()} users")
}
}
main()Compila pra:
- Lua 5.1 bytecode → roda em Neovim, Roblox (com
task.waitmapping), GMod, OpenResty. - Native via Cranelift → binário CLI standalone.
- WASM → browser ou edge.
Mesma fonte. Três alvos. Sem #ifdef.
Status (importante)¶
Pre-1.0 (0.1.0). Compila, executa, testa. APIs ainda mudam.
- Compilador: 25 crates Rust.
- Roadmap: ~68% concluído — veja PROGRESS.md.
- Plugins: 180+ implementados como cdylibs Rust (PLUGIN_ROADMAP.md).
- Tooling: LSP, formatter, DAP, REPL — todos funcionais.
Use pra escrever scripts, plugins, brincar, dar feedback. Não use em produção crítica ainda.
Próximo¶
- Getting Started — instale e rode seu primeiro
.zolo.