The standard library in daily use
table, math, string, os and io functions you actually call, plus the differences between Lua 5.1, 5.3, 5.4 and LuaJIT.
table and math
-- table: the workhorse
local t = { 3, 1, 2 }
table.insert(t, 4) -- append
table.insert(t, 1, 0) -- insert at position 1, shifting the rest
print(table.remove(t)) --> 4, removes the last
print(table.remove(t, 1)) --> 0
table.sort(t)
print(table.concat(t, ",")) --> 1,2,3
print(table.unpack({ 1, 2, 3 })) --> 1 2 3
-- Lua 5.1 called it unpack; 5.2+ moved it to table.unpack
local unpack = table.unpack or unpack
-- math
print(math.floor(3.7), math.ceil(3.2), math.max(1, 9, 4))
print(math.type(1), math.type(1.0)) --> integer float (5.3+)
print(math.tointeger(3.0), math.tointeger(3.5)) --> 3 nil
print(math.huge, -math.huge, math.pi)
print(math.random(1, 6)) -- seed it once: math.randomseed(os.time())
print(math.fmod(7, 3), 7 % 3) --> 1 1 (both are 1 here)
-- integer division and the modulo sign
print(7 // 2, -7 // 2) --> 3 -4
print(7 % 3, -7 % 3) --> 1 2 (result takes the divisor's sign)| Function | Returns | Note |
|---|---|---|
table.concat(t, sep) | A single string | Much faster than .. in a loop |
table.insert(t, [pos,] v) | Nothing | Shifts elements after pos |
table.remove(t, [pos]) | The removed value | Default is the last element |
table.unpack(t, i, j) | The elements as multiple values | Watch the stack size for large tables |
table.pack(...) | A table with a n field | Keeps trailing nils |
math.tointeger(x) | An integer or nil | Use it to test for a whole number |
math.type(x) | "integer", "float" or nil | Distinguishes 1 from 1.0 |
io and os
-- read a whole file
local function readAll(path)
local f, err = io.open(path, "rb")
if not f then return nil, err end
local content = f:read("a") -- 5.3+; in 5.1 use "*a"
f:close()
return content
end
-- read line by line for large files
for line in io.lines("data.csv") do
local field = line:match("^([^,]+)")
end
-- write
local out, err = io.open("out.txt", "w")
if not out then error("cannot open: " .. tostring(err)) end
out:write("header\n")
out:write(("row %d\n"):format(1))
out:close()
-- os functions you will actually use
print(os.time()) -- seconds since the epoch
print(os.date("%Y-%m-%d %H:%M:%S"))
print(os.date("!%Y-%m-%dT%H:%M:%SZ", 0))
print(os.clock()) -- CPU time, for measuring
local ok, why, code = os.execute("ls -1 | wc -l")
print(os.getenv("HOME"))
print(os.tmpname())- Always check the second return value of
io.open. A failed open returnsnilplus a message, and calling a method on nil gives a confusing error. io.linescloses the file automatically when the loop finishes, which is why it is the preferred form.os.executechanged its return values between versions. In 5.1 it returns an exit status; in 5.2 and later it returnstrueornilplus a reason and a code.os.removerenames and removes files; it does not delete directories. Use a shell call or a library for that, and be careful with paths built from input.
-- version differences that break real code
-- 5.1 unpack(t) | 5.2+ table.unpack(t)
-- 5.1 math.mod, math.log10 | 5.3+ math.fmod, removed log10
-- 5.1 setfenv / getfenv | 5.2+ _ENV and load
-- 5.2 bit32 library | 5.3+ native operators & | ~ << >>
-- 5.3+ integer subtype | LuaJIT: all numbers are doubles unless it uses FFI
-- 5.4 <close> and <const> | LuaJIT: not supported
-- # on a table with holes | any version: the result is undefined⚠️
LuaJIT is Lua 5.1 plus extensions. Code written for 5.4 will not run on it, and code that relies on LuaJIT's FFI or on its 64-bit integer behaviour will not run on the reference implementation. Decide which target you support before you use a version-specific feature.
FAQ
What does #t return for a table with holes?
Any boundary. The length operator is only defined for a sequence: a table where the keys are 1 through n with no nil in between. With holes the result is one of the possible boundaries, so track the length yourself.
How do I copy a table?
A shallow copy is
for k, v in pairs(t) do copy[k] = v end. A deep copy needs a recursive function and a visited set to handle shared references and cycles.Related
Strings and Lua patterns Tables, metatables and object orientation
Last refreshed 2026-09-18.