Luvit Runtime

Host Lua applications on Witchly.host with Luvit — a Node-like runtime for Lua. Great for Discordia Discord bots and lightweight services.

Luvit Runtime

Luvit is a Lua runtime in the style of Node.js, built on libuv. It’s lightweight, fast, and the standard runtime for Discordia — the popular Lua Discord library. Witchly’s egg clones a Git repo and runs your Lua entrypoint.

When to pick Luvit

  • You want to write a Discord bot in Lua with Discordia.
  • You’re comfortable with Lua and want a runtime with async I/O and libuv-powered performance.
  • You need small memory footprint — Luvit is lean.

Quick deploy

  1. dash.witchly.hostDeployLanguagesluvit generic.
  2. On the Startup tab, set:
    • Git Repo Address — your repo URL
    • lua file — entrypoint (default app.lua)
  3. Start.

Startup flow

./luvit {{LUA_FILE}}

The egg ships with the Luvit binary pre-installed in /home/container/. The install step clones your repo and any LIT_PACKAGES via lit install.

Variables reference

VariablePurpose
GIT_ADDRESSGit repo URL
BRANCHGit branch
USER_UPLOAD1 to skip clone (upload manually)
LUA_FILEEntrypoint (default app.lua)
LIT_PACKAGESLit packages to install (space-separated, e.g., SinisterRectus/discordia)
USERNAME, ACCESS_TOKENPrivate repo credentials

Discord bot with Discordia

-- app.lua
local discordia = require("discordia")
local client = discordia.Client()

client:on("ready", function()
  print("Logged in as " .. client.user.username)
end)

client:on("messageCreate", function(message)
  if message.content == "!ping" then
    message.channel:send("pong")
  end
end)

client:run("Bot " .. os.getenv("DISCORD_TOKEN"))

Set LIT_PACKAGES = SinisterRectus/discordia on the Startup tab so it installs on boot. Add DISCORD_TOKEN as an env var or hard-code it (not recommended).

Installing Lit packages manually

From the Console tab:

lit install SinisterRectus/discordia
lit install creationix/weblit

Packages install to ./deps/ in your server directory.

HTTP server with weblit

-- app.lua
local weblit = require("weblit")

local port = tonumber(os.getenv("SERVER_PORT"))

weblit.app
  .bind({host = "0.0.0.0", port = port})
  .use(weblit.logger)
  .use(weblit.autoHeaders)
  .route({method = "GET", path = "/"}, function(req, res)
    res.code = 200
    res.body = "Hello from Luvit!"
  end)
  .start()
LIT_PACKAGES = creationix/weblit

File system and I/O

Luvit’s core modules mirror Node’s: fs, path, net, http, timer, process. Files in /home/container/ are readable/writable:

local fs = require("fs")
local data = fs.readFileSync("config.json")

Troubleshooting

  • “module ‘discordia’ not found” — run lit install SinisterRectus/discordia or add it to LIT_PACKAGES.
  • Bot exits immediately — Discordia needs a valid token; a token with no intents will authenticate but receive no events.
  • “Permission denied” on ./luvit — the binary wasn’t chmod’d at install; run chmod +x luvit from the Console.

Next steps