Skip to content

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.

Terminal window
LUDI_WATCH=1 lua app.lua

Edit a route, save, refresh: the change is live.

  1. A change is detected (new, edited or deleted .lua file).
  2. Application modules are dropped from package.loaded, so require re-reads them. The Lua stdlib and Ludi itself are kept.
  3. The entrypoint (app.lua) is re-executed; its app: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.

  • State living in module locals is reset on reload, like restarting the process.
  • The listen callback does not run again — the port is bound once.
  • Files inside hidden directories, target/ and lua_modules/ are ignored.