Learn Lua in Neovim: Hello World with print() & :!lua % | Episode 1
Video: Learn Lua in Neovim: Hello World with print() & :!lua % | Episode 1 by Taught by Celeste AI - AI Coding Coach
Hello World in Lua: print() and Running Code in Neovim
Your first Lua program.
print()for output,:!lua %to run the current file from inside Neovim. The whole runtime in three lines.
Lua is the language behind Neovim plugins, Roblox, World of Warcraft addons, and a lot of game-engine scripting. This series teaches Lua from scratch while coding inside Neovim — two skills at once.
The first program is the canonical one: print "Hello, World!" and watch it appear.
Create the file
Inside Neovim:
:e hello.lua
:e (edit) opens a buffer; if the file doesn't exist, Neovim creates it on the next :w. The .lua extension tells Lua's interpreter (and Neovim) what kind of file this is.
The first line
print("Hello, World!")
print(...) is Lua's built-in output function. It takes any number of arguments, converts each to a string, and writes them to stdout separated by tabs, ending with a newline.
The string "Hello, World!" uses double quotes. Single quotes work too — 'Hello, World!' produces the same result. Pick whichever doesn't conflict with content ("It's me" vs 'She said "hi"').
Run the file
Save with :w, then run with:
:!lua %
Three pieces:
:!— run an external shell command from Neovim.lua— the Lua interpreter installed on your system.%— Neovim shorthand for "the current buffer's filename."
So :!lua % is "run the lua interpreter on this file." Output appears at the bottom of Neovim.
Add more lines
print("Hello, World!")
print("My name is Lua")
print("Welcome to")
print("Learn Lua in Neovim!")
print("Time to start coding!")
Each print() produces one line of output. Lua executes top to bottom; there's no main(), no compilation step, no boilerplate.
To open a new line below the cursor in Neovim, press o in normal mode. It opens the line and drops you into insert mode in one keystroke — much faster than : o or arrow + return.
Why no semicolons?
Lua treats newlines as statement separators by default. You can put semicolons (print("a"); print("b")) when stacking statements on one line, but they're optional and most code skips them.
What print actually does
print("a", 42, true)
Outputs a 42 true — three values, tab-separated, ending with newline. Internally:
- Each argument goes through
tostring()to become a string. - The result is written to standard output.
For more control over formatting, use io.write() (no automatic separators or newline) or string.format() (printf-style).
Common stumbles
:!lua % says command not found. Lua isn't installed. On macOS: brew install lua. On Ubuntu/Debian: sudo apt install lua5.4. On Windows: download from lua.org or use scoop install lua.
The output flashes and disappears. Neovim buffers :! output briefly. Press <Enter> to dismiss the prompt and return to your buffer; the output remains in the message history (:messages).
Forgot to save before running. :!lua % runs the file on disk, not the unsaved buffer. Always :w first. Or chain it: :w | !lua %.
Mixing tabs and spaces. Lua doesn't care about indentation (it's whitespace-insensitive), but mixed tabs/spaces look wrong in diffs and other tools. Pick one. Two-space indent is the community norm.
What's next
Episode 2: variables and types. local, the four basic types (string, number, boolean, nil), and the type() function for inspection.
Recap
print("text") writes a line to the screen. :!lua % runs the current file from inside Neovim. Lua runs top-to-bottom — no main() entry point. Save with :w before running. Press o in normal mode to add a new line below.
Next episode: variables and types.