Standard Lua AST Libraries
These libraries target Lua 5.1, 5.2, and 5.3. They are suitable for general Lua obfuscation, game modding, and embedded scripting environments.luaparse (JavaScript/Node.js)
luaparse is the most widely used Lua parser in the JavaScript ecosystem. It supports Lua 5.1, 5.2, and 5.3 and produces a JSON-compatible AST. It is an excellent choice if you want to build obfuscation tooling in Node.js.metalua (Lua)
metalua is a historical Lua-based parser and AST library designed for macro programming and metaprogramming. It includes a complete Lua parser written in Lua itself and provides utilities for AST traversal and transformation.lua-parser (LuaRocks)
Several community Lua parsers are available on LuaRocks and GitHub. Search for packages likelua-parser or lua-ast to find implementations in various languages. Quality varies, so evaluate based on:
- Which Lua versions are supported
- Whether the AST includes location information
- Whether a serializer/printer is included
- Test coverage and maintenance activity
LPeg-Based Parsers
LPeg is a pattern-matching library for Lua based on Parsing Expression Grammars (PEGs). It enables writing grammar-based parsers in pure Lua. While building a full Lua parser with LPeg is complex, it is feasible and gives you complete control over the AST structure. Here is a tiny LPeg grammar snippet for parsing Lua identifiers:lua-parser (the LPeg-based one) provide this out of the box.
Luau-Specific Parsers
Luau is Roblox’s fork of Lua 5.1 with additional type syntax and optimizations. Standard Lua parsers often choke on Luau-specific syntax, so you need a Luau-aware parser for Roblox-related obfuscation.luau-ast (Official Luau Repo)
The Luau open-source repository includes an official C++ parser that exposes an AST. You can access it by building the Luau CLI tools from source or by linking against the Luau library in a C++ project.luau-analyze for type checking and luau-compile for compilation. For AST-based obfuscation, you would use the C++ AST API directly or pipe the output through a custom tool.
full-moon (Rust)
full-moon is a Lua 5.1 and Luau parser written in Rust. Its key differentiator is lossless CST output: it preserves whitespace, comments, and every token exactly as it appeared in the source. This makes it ideal for building obfuscation tools where you need fine-grained control over output formatting.darklua (Rust)
darklua is a Lua/Luau source transformation tool written in Rust, specifically designed for bundling and obfuscation. It supports configurable transforms via a JSON configuration file and is one of the most production-ready open-source options for Lua/Luau obfuscation.Building an Obfuscation Pipeline with darklua
darklua provides a declarative configuration system where you enable transforms by name in a JSON file. It handles parsing, transformation, and serialization automatically.Installation
Configuration File
Create adarklua.json file that enables multiple obfuscation rules:
Running darklua
process command reads input.lua, applies all enabled rules in order, and writes the obfuscated output to output.lua. Available rules include:
Building a Custom Pipeline in Node.js with luaparse
For maximum control over your obfuscation logic, you can build a custom pipeline in Node.js using luaparse for parsing and a custom printer for serialization.Step 1: Parse Source to AST
Step 2: Walk and Transform the AST
Step 3: Serialize Back to Lua Source
luaparse does not include a built-in printer, so you need a custom serializer. Here is a minimal printer for the core node types:Complete Pipeline Script
Here is a complete ~40-line Node.js script that parses, renames identifiers, and prints the result:Testing Your Obfuscated Output
Every obfuscation pipeline must include verification that the transformed code behaves identically to the original.1
Run Original Test Suite
Execute your full test suite against the unmodified source to establish a baseline.
2
Obfuscate and Execute
Run the same test suite against the obfuscated output using
lua or luau CLI:3
Compare Outputs
Diff the stdout, stderr, and any file outputs between the original and obfuscated runs. They must match exactly.
4
Fuzz with Random Inputs
If your code accepts inputs, generate random test cases and verify both versions produce identical results.
Accordion: Common Questions
Can I use LuaJIT's built-in parser?
Can I use LuaJIT's built-in parser?
LuaJIT includes a built-in parser as part of its compiler pipeline, but it is not exposed as a public API for AST extraction. The parser is tightly coupled to LuaJIT’s bytecode generation and does not produce a standalone AST that you can manipulate. For tooling purposes, use luaparse, full-moon, or darklua instead.
Is there a ready-made Lua obfuscator built on AST transforms?
Is there a ready-made Lua obfuscator built on AST transforms?
darklua is the most production-ready open-source option that uses AST-level transforms internally. It supports both Lua and Luau and provides configurable rules via JSON. For the Roblox ecosystem, Prometheus is a community obfuscator that also uses AST-level transforms internally, though it is not open source. If you need full control, building a custom pipeline with luaparse or full-moon is the recommended approach.
Which parser should I choose for Luau?
Which parser should I choose for Luau?
If you need lossless output (preserving comments and formatting), use full-moon. If you need a CLI-driven workflow with built-in obfuscation rules, use darklua. If you are building a C++ tool and need the official parser, use luau-ast from the Luau repository.
Next Steps
With your parser and pipeline chosen, you can now implement the specific obfuscation techniques:AST Transformations
Learn the core AST transforms: renaming, splitting, reordering, and inlining.
AST Overview
Understand the structure and node types of the Lua AST.
Bytecode Obfuscation
Explore bytecode-level obfuscation for deeper protection.
