Why this page exists: Lua
Here you can try Lua in a constrained runner that favors clarity over project setup. The work area is meant for quick edits, quick failures, and quick confirmation when a language rule is fuzzy.
Runs Lua via Piston from main.lua, using the Lua build exposed by the current runner. The page returns output after the runner or preview finishes, which is usually only a few seconds for the kind of examples that belong here.
Tables are both arrays and maps, and the array-style part starts at index 1 by convention. We would rather be blunt about that limit than make the page sound bigger than it is.
What it cannot prove
The runner is not a production environment. It will not carry durable state between serious sessions, and it should not be asked to handle native modules, embedded host APIs, long-running loops, and file-system assumptions. Good. Boundaries make bugs easier to see.
The sweet spot is tables, metatables in miniature, loops, string functions, and game-scripting style snippets. If your example needs a package manager, a database full of private rows, a web server listening on a port, or special build flags, move it to a local workspace before you draw conclusions.
A small runner should feel disposable. Try the idea, keep the useful lesson, and leave the accidental environment behind when the next step needs real project context.
Behind the scenes
- Start with the smallest Lua snippet that can show the behavior.
- Add input only when the program reads it. Empty STDIN is a valid test case.
- Press Run, inspect stdout and stderr, then change one line. That rhythm keeps accidental fixes from hiding the real bug.
The page keeps the run path short. We keep the run cycle compact because this page is meant to answer one question at a time, not manage a full project tree.
That style also makes the result easier to share. A reader can scan a short Lua snippet, run it, and see the same error without first recreating your directory structure or guessing which dependency you forgot to mention.
Concrete example
The saved example below is intentionally left unchanged. Run it once as written, then make a small edit and run it again; that gives you a known-good baseline before you test your own idea.
local Greeter = {}
Greeter.__index = Greeter
function Greeter.new(greeting)
local self = setmetatable({}, Greeter)
self.greeting = greeting or "Hello"
return self
end
function Greeter:greet(name)
if name and name ~= "" then
print(self.greeting .. ", " .. name .. "!")
else
print(self.greeting .. ", stranger!")
end
end
local g = Greeter.new("Welcome")
local name = io.read("*l")
g:greet(name)
The next preserved block belongs to the same example. Keep it nearby when you are comparing input, output, or the shape of the result. Small examples expose mistakes quickly.
Welcome, Alice!
After the sample works, try one edge case that exercises the page's limits. Tables are both arrays and maps, and the array-style part starts at index 1 by convention. That single change often teaches more than pasting a large program and trying to guess which part failed.
Practical uses
Use it when you are stuck on someone else's machine, teaching a small concept, or separating a language question from a project question. No ceremony.
It also works well as a note-taking tool: paste the final snippet into your lesson, issue, or commit message after you have proved it in the runner.
Keep the example slightly smaller than feels natural. That sounds fussy, but it prevents a common debugging mistake: changing five pieces of code, getting a different result, and no longer knowing which piece mattered.
Questions from the editor
Only a few questions belong here. The goal is to answer the mistakes that actually interrupt a small Lua run, not to pad the page.
How to compile Lua code?
Lua code is normally loaded and run by the Lua interpreter, but Lua also compiles chunks to bytecode internally. Locally, luac can write bytecode files, though many people simply run lua main.lua. For this page, focus on script behavior: tables, functions, loops, and printed output. For example, lua main.lua runs a local Lua script. Lua tables are flexible, but nil values and one-based array conventions are easy places to get surprised.
Is Lua compiled or interpreted?
Lua is often described as interpreted, but it compiles source into bytecode before running it on the Lua virtual machine. That bytecode step is usually invisible. The useful mental model is simple: write a small script, run it, and check the output, rather than expecting a separate executable build. Lua tables are flexible, but nil values and one-based array conventions are easy places to get surprised.
Can you compile Lua with GCC?
Lua code is normally loaded and run by the Lua interpreter, but Lua also compiles chunks to bytecode internally. Locally, luac can write bytecode files, though many people simply run lua main.lua. For this page, focus on script behavior: tables, functions, loops, and printed output. For example, lua main.lua runs a local Lua script. Lua tables are flexible, but nil values and one-based array conventions are easy places to get surprised.
Is this Lua playground free to use?
Yes, totally free - no signup, no account, no usage limits for normal practice. The editor and the Lua runtime both run in your browser session.
Can I use this for Lua programming practice?
Yes - Lua tables, metatables, coroutines, string patterns, and OOP-style modules all work for practice. For Lua embedded in a game engine or used as a config language, you'll need the host application; for pure Lua experiments, this page is enough.
Documentation
Reference pages are better than folklore when an error message gets specific. Start with official docs, then use tutorials for context once the rule is clear.
Related compilers
One last practical note: keep a tiny passing snippet next to the failing one. The comparison often makes the missing assumption obvious, and it keeps the page useful without turning a quick runner into a pretend project workspace.
Lua rewards that style because tables, nil checks, and function return values can change the shape of a program quickly. If a snippet surprises you, print the table keys, check whether a value is actually nil, and rerun before adding another abstraction.