luacheck: Lint Lua Code in CI
luacheck scans Lua files for undefined globals, unused variables, and shadowing, exiting 1 on warnings and higher on errors.
luacheck is the standard Lua linter, widely used for Neovim configs and OpenResty code. In CI you run it over the sources with a declared standard.
What it does
luacheck takes files or directories, applies its checks against a chosen Lua standard library set (--std), and reports warnings (W) and errors (E). It exits 0 when clean, 1 when only warnings are found, and higher codes for errors or its own failures.
Common usage
luacheck src/
# declare the Lua flavor and extra globals
luacheck --std luajit --globals vim -- src/
# format for CI parsing
luacheck --formatter plain src/Flags
| Flag | What it does |
|---|---|
| <paths> | Files or directories to check |
| --std <name> | Standard globals set (lua54, luajit, min, ngx_lua) |
| --globals <names> | Declare additional allowed read/write globals |
| --ignore <patterns> | Ignore warning codes or variable patterns |
| --formatter <name> | Output format (default, plain, TAP, JUnit) |
| --no-color | Disable colored output (cleaner CI logs) |
In CI
Set --std to match your runtime (luajit for LuaJIT/OpenResty, lua54 for Lua 5.4) or every standard-library call is flagged as an undefined global. Use --formatter plain or JUnit so the output parses cleanly in CI rather than the boxed default format.
Common errors in CI
"W113 accessing undefined variable 'vim'" means a global the linter does not know about; declare it with --globals or in .luacheckrc. "W211 unused variable" and "W212 unused argument" are the most common style warnings. A wrong --std value floods the report with false undefined-global warnings for standard functions.