Skip to content

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

bash
npm i -g luaudocs
bash
# tracks the latest commit
npm i -g github:kohltastrophe/luaudocs

Your first site

bash
cd my-luau-library && luaudocs dev

That 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:

examples/Flux/init.luau
luau
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 Flux

That module's page is below, embedded from the markdown LuauDocs emitted for it:

Properties

State Module

luau
Flux.State: State

Util Module

luau
Flux.Util: Util

Functions

state

luau
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

luau
Flux.isState(value: any): boolean

Reports 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.State and Flux.Util).
  • isState is documented under the name callers use, badged from State so readers know where it is defined.
  • The signatures are your annotations, with State.State linking 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: FluxUtilQueue. 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 dev watches your sources and serves the live preview you just used.
  • luaudocs build writes the static site, ready to publish. See Deploying.
  • luaudocs init scaffolds a luaudocs.toml and 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

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.