If you have used Express.js, Koa, or Sinatra, Wapka’s Lua framework will feel immediately familiar. The syntax is designed to be recognizable — on purpose.
A quick tour
local app = framework()
app:get("/", function(ctx)
return ctx:html("<h1>Hello from Lua</h1>")
end)
app:get("/api/users", function(ctx)
local users = api.users.list({ limit = 50 })
return ctx:json(users)
end)
app:post("/api/contact", function(ctx)
local name = ctx.body.name
local email = ctx.body.email
api.dataset.create("messages", {
name = name,
email = email
})
return ctx:json({success = true})
end)
Route definitions. Request parameters. Database queries. JSON responses. Standard web development patterns — running inside a sandboxed Lua environment via PHP LuaSandbox.
What the framework provides
- Routing:
app:get,app:post,app:put,app:delete— standard HTTP method routing - Parameter parsing: URL params (
:id), query strings, request bodies - Response formatting: HTML, JSON, plain text, file downloads
- Database access: Dataset API with collection queries
- Session management: User authentication state across requests
- File access: Read and write files in the user’s storage
All of this runs with kilobyte memory footprints and microsecond startup times.
Why the Express-like design
When we designed the framework, we had a choice: invent a new DSL, or model it after something millions of developers already know. We chose the latter.
Familiarity lowers the barrier. A developer who knows Express can pick up Wapka’s Lua framework in minutes. The concepts transfer. The syntax transfers. The mental model transfers.
For the platform’s target audience — students learning backend development, creators adding their first dynamic features — this familiarity is the difference between “I can do this” and “I need to learn an entirely new system.”
Continue reading: Why Lua? The architectural decision → The database builder: visual CRUD without SQL →