Getting Started
LuauDocs reads a Luau library and builds a documentation site from it: the exports are discovered for you, the signatures come from the annotations already in your code, and the result is a VitePress site with search, dark mode, and cross-linked types. There is nothing to tag and no configuration required upfront.
Requirements
Node.js 22.12 or newer.
Reading Luau sources also needs Lute, but you do not have to install it: the first extraction downloads and caches a pinned build for you. (On a machine with no internet access, point LUAUDOCS_LUTE at your own copy instead.)
Install
npm i -g luaudocs# tracks the latest commit
npm i -g github:kohltastrophe/luaudocsYour first site
cd my-luau-library && luaudocs devThat is the whole setup. dev prints a localhost URL, and your API reference is already on it.
You have no luaudocs.toml, so LuauDocs uses defaults: the site title comes from the folder name, and it reads modules from src/ and lib/ (if your sources live elsewhere, specify them with [source] entries). Without an existing .luaudocs/ directory, the build creates one and generates the entire site inside it. It is safe to commit as-is: an auto-generated .gitignore covers all build artifacts, leaving the rest for you to author.
Leave dev running while you work. Edit a doc comment and the page updates in place.
What you just got
Here is a real library: this site ships examples/Flux and documents it with the same commands you just ran:
local State = require("@self/State")
local Util = require("@self/Util")
--[[ A tiny reactive state library. ]]
local Flux = {}
Flux.State = State
Flux.Util = Util
--[[ Reports whether `value` is a state. ]]
Flux.isState = State.isState
--[[
Creates a state holding `initial`.
Call the state to read it, and see [State:Connect] for reacting to changes.
]]
function Flux.state<T>(initial: T?): State.State<T>
return State.new(initial)
end
return FluxThat module's page is below, embedded from the markdown LuauDocs emitted for it:
Properties
State Module
Flux.State: StateUtil Module
Flux.Util: UtilFunctions
state
Flux.state<T>(initial: T?): State.State<T>Creates a state holding initial.
Call the state to read it, and see State:Connect for reacting to changes.
isState from State
Flux.isState(value: any): booleanReports whether value is a state.
Here is how LuauDocs processed the file:
- The two required modules became pages, badged Module and linked. They sit under Flux in the sidebar, matching the access paths callers use (
Flux.StateandFlux.Util). isStateis documented under the name callers use, badged from State so readers know where it is defined.- The signatures are your annotations, with
State.Statelinking to the page documenting that type. [State:Connect]resolves into a link, because a module in the project declares it.
You wrote no tags and no config. LuauDocs inferred everything from what return Flux evaluates to, and How It Works explains how; read it once and nothing about your sidebar will look mysterious.
TIP
The whole example is browsable under Example API, nested exactly as it is reached: Flux → Util → Queue. Every framed block in these guides is embedded from it, and its label links to the entry it came from.
Commands
Three commands, and every one of them takes an optional project directory (default .):
luaudocs devwatches your sources and serves the live preview you just used.luaudocs buildwrites the static site, ready to publish. See Deploying.luaudocs initscaffolds aluaudocs.tomland the pages you own, for when you want to shape the site. See Configuration.
--help prints the flags, and Reference: CLI documents all of them.
Next steps
- How It Works - why your site contains what it contains.
- Writing Doc Comments - the prose layer on top.
- Configuration -
luaudocs.toml, the filesinitwrites, and styling. - Deploying - GitHub Pages from one workflow file.
Already using Moonwave?
luaudocs init --from-moonwave converts your config and hand-written pages and copies your assets, and all 24 Moonwave tags keep working as-is. See Migrating from Moonwave.