Lua Cheat Sheet
Last updated
Hello World & running code
Lua is minimal - a single statement runs.
| Operation | Syntax |
|---|---|
| Print a line | print("Hello, World!") |
| Print multiple values | print("x", 1, true) |
| Write without newline | io.write("Hi") |
| Comment | -- this is a comment |
| Multi-line comment | --[[ ... ]] |
| Concatenate strings | print("Hi " .. name) |
| Run a file | lua app.lua |
| Interactive shell | lua |
Variables & types
Variables are global by default; declare locals with local.
| Operation | Syntax |
|---|---|
| Local variable | local age = 30 |
| Global variable | count = 0 |
| Multiple assignment | local a, b = 1, 2 |
| The eight types | nil, boolean, number, string, table, function, userdata, thread |
| Nil / booleans | nil, true, false |
| Check type | type(x) returns "number" |
| Convert to number | tonumber("42") |
| Convert to string | tostring(42) |
Strings
Strings are immutable; both single and double quotes work.
| Operation | Syntax |
|---|---|
| Length | #s or string.len(s) |
| Concatenate | s1 .. s2 |
| Uppercase / lowercase | s:upper(), s:lower() |
| Substring | s:sub(1, 3) |
| Find substring | s:find("ell") |
| Replace (gsub) | s:gsub("a", "b") |
| Format | string.format("%05d", 42) |
| Long string | [[ multi\nline ]] |
Tables (the core data structure)
Tables are Lua's only structured type - they act as arrays, maps, and objects.
| Operation | Syntax |
|---|---|
| Empty table | local t = {} |
| Array-style (1-based) | local t = {10, 20, 30} |
| Access array element | t[1] (first element) |
| Map-style table | local u = {name = "Ada", age = 30} |
| Access map value | u.name or u["name"] |
| Set a value | t[4] = 40, u.email = "a@x.com" |
| Length of array part | #t |
| Iterate array (ipairs) | for i, v in ipairs(t) do ... end |
| Iterate all keys (pairs) | for k, v in pairs(u) do ... end |
| Nested table | local m = {a = {1, 2}} |
Control flow
Blocks close with end; only nil and false are falsy.
| Operation | Syntax |
|---|---|
| If / elseif / else | if x > 0 then ... elseif x < 0 then ... else ... end |
| Logical operators | and, or, not |
| Numeric for | for i = 1, 10 do ... end |
| For with step | for i = 10, 1, -1 do ... end |
| While loop | while x < 100 do ... end |
| Repeat-until | repeat ... until done |
| Break | break |
| Not-equal operator | if a ~= b then ... end |
Functions
Functions are first-class values and can return multiple results.
| Operation | Syntax |
|---|---|
| Define a function | function add(a, b) return a + b end |
| Local function | local function square(x) return x * x end |
| Anonymous function | local f = function(x) return x * 2 end |
| Multiple return values | function bounds() return 1, 10 end |
| Capture multiple returns | local lo, hi = bounds() |
| Variadic function | function sum(...) ... end |
| Collect varargs | local args = {...} |
| Method (colon syntax) | function obj:greet() ... end |
String library
Common functions from the string library (callable as s:fn()).
| Function | What it does |
|---|---|
string.len(s) | Length of the string |
string.sub(s, i, j) | Substring from index i to j |
string.upper(s) | Uppercase copy |
string.rep(s, n) | Repeat the string n times |
string.find(s, p) | Find a pattern, returns start/end |
string.match(s, p) | Return first pattern match |
string.gsub(s, p, r) | Replace all pattern matches |
string.format(fmt, ...) | Format values into a string |
Table & math libraries
Helpers for working with array-style tables and numbers.
| Function | What it does |
|---|---|
table.insert(t, v) | Append a value to the end |
table.insert(t, i, v) | Insert v at position i |
table.remove(t, i) | Remove and return element at i |
table.concat(t, ", ") | Join elements into a string |
table.sort(t) | Sort the array in place |
math.floor(x) / math.ceil(x) | Round down / up |
math.max(...) / math.min(...) | Largest / smallest argument |
math.random(1, 6) | Random integer in a range |
Metatables (brief)
Metatables let you customize how tables behave - operators, indexing, and more.
| Operation | Syntax |
|---|---|
| Set a metatable | setmetatable(t, mt) |
| Get a metatable | getmetatable(t) |
| Fallback for missing keys | mt.__index = defaults |
| Default via function | mt.__index = function(t, k) ... end |
| Customize addition | mt.__add = function(a, b) ... end |
| Customize tostring | mt.__tostring = function(t) ... end |
| Prototype-based OOP | mt.__index = ClassTable |
The Lua syntax you reach for most, on one page. This Lua cheat sheet is a quick reference for the core language - variables and types, strings, control flow, functions, and the tables that serve as Lua's single, flexible data structure, plus a peek at the standard libraries and metatables.
Everything here is standard Lua and runs on a stock interpreter. Copy what you need, or try every snippet live in the Lua playground - no install required.
Lua cheat sheet FAQ
Is this Lua cheat sheet free?
How can a Lua table be both an array and a map?
{10, 20, 30}) the table behaves like an array; when you use string keys ({name = "Ada"}) it behaves like a map. You can even mix both in the same table. This is why Lua only needs one structured type - the table covers arrays, dictionaries, sets, and objects.Why does Lua use 1-based indexing?
t[1] is the first element and #t is the count. The length operator # and library functions like table.insert and ipairs all assume this 1-based convention, so sticking to it keeps your array code working as expected.