Getting Started
Installation
VS Code
Install the wowlua-ls extension from the VS Code marketplace. It bundles the language server binary — no separate install needed.
JetBrains IDEs
Download the plugin ZIP for your platform from GitHub Releases and install via Settings → Plugins → ⚙️ → Install Plugin from Disk.... Requires the LSP4IJ plugin. The release ZIPs bundle the language server binary — no separate install needed.
Other editors
Build the language server from source:
git clone https://github.com/TradeSkillMaster/wowlua-ls.git
cd wowlua-ls
cargo build --releaseThe binary is at target/release/wowlua_ls. Configure your editor to run it as an LSP server over stdio for Lua files.
Your first project
Open a WoW addon folder in your editor. wowlua-ls will automatically:
- Scan all
.luafiles in the workspace - Load the built-in WoW API stubs (retail + classic)
- Resolve cross-file classes, globals, and addon namespaces
- Start reporting diagnostics
No configuration file is required to get started. The defaults are sensible for most addons.
Adding a configuration file
For project-specific settings, create a .wowluarc.json in your addon's root directory:
{
"ignore": ["Libs/"],
"flavors": ["retail", "classic"],
"diagnostics": {
"enable": ["need-check-nil"]
}
}This tells wowlua-ls:
- Skip
Libs/— don't analyze third-party library code - Target retail and classic — warn about flavor-specific APIs
- Enable nil checking — report
need-check-nilwarnings (off by default)
See Configuration for the full reference.
Adding annotations
wowlua-ls infers a lot on its own, but annotations make it smarter. Start with the high-value ones:
Annotate your public API
---@param itemId number
---@param count number?
---@return boolean success
---@return string? error
function MyAddon:BuyItem(itemId, count)
if not self.store then
return false, "store not initialized"
end
-- ...
return true
endThe LS now knows the parameter types, that count is optional, and that the function returns a boolean plus an optional error string. Every caller gets type checking and hover information.
Annotate your classes
---@class AuctionEntry
---@field itemId number
---@field buyout number
---@field seller string
---@field duration number?Now AuctionEntry is a named type. You can reference it in @param and @return annotations across your codebase, and the LS will provide completion and type checking for its fields.
When to use @type
@type forces a variable's type. It's most useful when the LS can't infer what you need. For cases where the LS already has the answer, it's up to you — the annotation won't hurt, but you can save yourself the effort:
-- Useful: tells the LS what this empty table will hold
---@type AuctionEntry[]
local entries = {}
-- Useful: the LS can't infer the type from nil alone
---@type Frame?
local cachedFrame = nil
-- Optional: the LS already infers this from the assignment
---@type number
local x = 5What to annotate next
Once you've annotated your core classes and public functions, the LS handles most of the rest through inference. When you see a ? type on hover (meaning the LS couldn't figure it out), that's a signal to add an annotation.
