Module Patterns and Best Practices
Use local M = {} pattern and expose public API cleanly.
The M = {} Pattern
The universal Lua module pattern: declare a local table, populate it, return it. All public symbols go in M; all private helpers are plain locals. This is clear, minimal, and works everywhere.
-- The canonical module pattern
local M = {}
-- Private helper (not exported)
local function validate(x)
return type(x) == "number" and x >= 0
end
-- Public API
function M.sqrt(x)
assert(validate(x), "expected non-negative number")
return math.sqrt(x)
end
M.PI = math.pi
return MSelf-Referential Module
Inside a module, functions can call other module functions either by name (M.foo()) or as locals. Using locals is slightly faster; using M.foo() allows users to override M.foo and have the internal call use the override (monkey patching).
local M = {}
-- Option A: use M.foo inside (allows override)
function M.double(n) return M.multiply(n, 2) end
function M.multiply(a, b) return a * b end
-- Option B: use local function (faster, no override)
local function mul(a, b) return a * b end
function M.triple(n) return mul(n, 3) end
return MAll lessons in this course
- The require Function
- Writing a Module File
- package.path and package.cpath
- Module Patterns and Best Practices