Hot reload
With LUDI_WATCH=1, Ludi watches every *.lua file under the working
directory and hot-reloads the application on change — no restart, no
rebinding the port, in-flight requests are never interrupted.
LUDI_WATCH=1 lua app.luaEdit a route, save, refresh: the change is live.
How it works
Section titled “How it works”- A change is detected (new, edited or deleted
.luafile). - Application modules are dropped from
package.loaded, sorequirere-reads them. The Lua stdlib and Ludi itself are kept. - The entrypoint (
app.lua) is re-executed; itsapp:listen()call is intercepted and the new app replaces the old one in place.
The reload runs on the Lua thread, between requests — never in the middle of one. A reload that fails (syntax error, error at load time) prints a framed source excerpt on stderr — offending line highlighted, carets under the token the parser choked on — and the previous version keeps serving until the next change:
reloading (app.lua changed)
✗ Syntax error — keeping previous version
app.lua:12 ')' expected (to close '(' at line 10) near 'end'
10 │ app:get("/users", function(_, res) 11 │ res:json({ users = users }) ▶ 12 │ end │ ^^^
Fix the file and save to reload.A successful reload prints ✓ reloaded. Colors are disabled when
NO_COLOR is set or the terminal is dumb.
Semantics
Section titled “Semantics”- State living in module locals is reset on reload, like restarting the process.
- The
listencallback does not run again — the port is bound once. - Files inside hidden directories,
target/andlua_modules/are ignored.
