Skip to main content

Overview

emmylua_doc is a documentation generator that extracts EmmyLua annotations and code structure from your Lua projects to create comprehensive, formatted API documentation. It supports multiple output formats including Markdown and JSON.

Installation

cargo install emmylua_doc_cli

Basic Usage

emmylua_doc_cli ./src

Command-Line Options

Positional Arguments

WORKSPACE
path[]
required
One or more paths to workspace directories containing Lua source files to document.
# Single workspace
emmylua_doc_cli ./src

# Multiple workspaces
emmylua_doc_cli ./src ./lib ./plugins

# Current directory
emmylua_doc_cli .

Configuration Options

--config
path[]
Comma-separated list of configuration file paths.If not provided, searches for .emmyrc.json or .luarc.json in the workspace directory.
# Auto-detect configuration
emmylua_doc_cli ./src

# Single config file
emmylua_doc_cli ./src --config ./.emmyrc.json

# Multiple configs
emmylua_doc_cli ./src --config ./config1.json,./config2.json

File Filtering Options

--exclude
string[]
Comma-separated list of glob patterns to exclude from documentation generation.Takes precedence over include patterns. Also available as --ignore.
# Exclude test files
emmylua_doc_cli ./src --exclude "**/*_test.lua,**/*_spec.lua"

# Exclude build and vendor directories
emmylua_doc_cli ./src --exclude "**/build/**,**/vendor/**,**/node_modules/**"

# Using alias
emmylua_doc_cli ./src --ignore "**/internal/**"
--include
string[]
Comma-separated list of glob patterns to include in documentation generation.
# Only document API files
emmylua_doc_cli ./src --include "**/api/**/*.lua"

# Multiple patterns
emmylua_doc_cli ./src --include "**/api/**/*.lua,**/lib/**/*.lua"

# Combine with exclude
emmylua_doc_cli ./src \
  --include "**/src/**/*.lua" \
  --exclude "**/*_test.lua"

Output Options

--output-format
string
default:"markdown"
Specify the output format for generated documentation.Available values:
  • markdown - Markdown documentation (default)
  • json - Structured JSON output
# Markdown output (default)
emmylua_doc_cli ./src --output-format markdown

# JSON output for custom processing
emmylua_doc_cli ./src --output-format json --output ./api.json
--output
string
default:"./output"
Specify the output destination.
  • For Markdown format: Directory where documentation files will be created
  • For JSON format: File path or stdout
# Default output directory
emmylua_doc_cli ./src
# Creates: ./output/

# Custom output directory
emmylua_doc_cli ./src --output ./api-docs

# JSON to stdout
emmylua_doc_cli ./src --output-format json --output stdout

# JSON to file
emmylua_doc_cli ./src --output-format json --output ./api.json

Customization Options

--override-template
path
Path to a custom template directory for overriding default documentation templates.
# Use custom templates
emmylua_doc_cli ./src --override-template ./doc-templates
Template structure:
doc-templates/
├── module.md.hbs      # Module page template
├── function.md.hbs    # Function documentation
├── class.md.hbs       # Class documentation
└── index.md.hbs       # Index page template
--site-name
string
default:"Docs"
Name of the documentation site, used in generated titles and metadata.
# Default site name
emmylua_doc_cli ./src

# Custom site name
emmylua_doc_cli ./src --site-name "MyAPI Documentation"

# Project-specific name
emmylua_doc_cli ./src --site-name "Awesome Lua Library API"
--mixin
path
Directory containing additional content to merge with generated documentation.Files in the mixin directory override generated files with the same path.
# Add custom content
emmylua_doc_cli ./src --mixin ./doc-mixin
Example structure:
doc-mixin/
├── index.md           # Custom home page
├── getting-started.md # Additional guide
└── assets/
    └── logo.png       # Custom assets
Override behavior:
  • If output/index.md is generated and mixin/index.md exists, the mixin version is used
  • Additional files in mixin are copied to output
  • Useful for adding guides, tutorials, and custom content

Other Options

--verbose
boolean
Enable verbose output with detailed progress information.
# Standard output
emmylua_doc_cli ./src

# Verbose mode
emmylua_doc_cli ./src --verbose
Verbose output includes:
  • File-by-file processing status
  • Template application details
  • Workspace loading information
  • Output file creation details

Deprecated Options

--input
path[]
Deprecated: Use WORKSPACE positional argument instead.
# Old (deprecated)
emmylua_doc_cli --input ./src --input ./lib

# New (recommended)
emmylua_doc_cli ./src ./lib
--format
string
Deprecated: Use --output-format instead.
# Old (deprecated)
emmylua_doc_cli ./src --format json

# New (recommended)
emmylua_doc_cli ./src --output-format json

Documentation Generation Process

Step 1: Preparation

Ensure your Lua code includes EmmyLua annotations:
--- A utility module for string operations
---@module string_utils

--- Splits a string by delimiter
---@param str string The string to split
---@param delimiter string The delimiter to split by
---@return table A table of split strings
function split(str, delimiter)
    local result = {}
    -- Implementation
    return result
end

--- Represents a user in the system
---@class User
---@field id number User's unique identifier
---@field name string User's display name
---@field email string User's email address
local User = {}

Step 2: Generate Documentation

emmylua_doc_cli ./src --output ./docs

Step 3: Review Generated Files

For Markdown output, the structure typically includes:
output/
├── index.md                 # Documentation home page
├── modules/
│   ├── string_utils.md     # Module documentation
│   └── math_helpers.md
├── classes/
│   ├── User.md             # Class documentation
│   └── Config.md
└── functions/
    └── global_functions.md # Global functions

Output Formats

Markdown Format (Default)

Generates organized Markdown documentation:
emmylua_doc_cli ./src --output ./docs
Features:
  • Organized by modules, classes, and functions
  • Includes type information and parameter details
  • Cross-references between documented items
  • Supports custom templates via --override-template
  • Can be used with static site generators (MkDocs, Docusaurus, etc.)
Example generated file:
# string_utils

A utility module for string operations

## Functions

### split

Splits a string by delimiter

**Parameters:**
- `str` (string): The string to split
- `delimiter` (string): The delimiter to split by

**Returns:**
- table: A table of split strings

**Usage:**
```lua
local parts = split("a,b,c", ",")
-- Result: {"a", "b", "c"}

### JSON Format

Generates structured JSON for custom processing:

```bash
emmylua_doc_cli ./src --output-format json --output api.json
Example JSON structure:
{
  "modules": [
    {
      "name": "string_utils",
      "description": "A utility module for string operations",
      "functions": [
        {
          "name": "split",
          "description": "Splits a string by delimiter",
          "parameters": [
            {
              "name": "str",
              "type": "string",
              "description": "The string to split"
            },
            {
              "name": "delimiter",
              "type": "string",
              "description": "The delimiter to split by"
            }
          ],
          "returns": [
            {
              "type": "table",
              "description": "A table of split strings"
            }
          ]
        }
      ]
    }
  ],
  "classes": [...],
  "globals": [...]
}
Use cases:
  • Custom documentation site builders
  • API documentation aggregation
  • IDE integration
  • Automated documentation testing

Workflow Examples

Static Site Generation with MkDocs

  1. Generate Markdown documentation:
emmylua_doc_cli ./src --output ./docs/api
  1. Configure mkdocs.yml:
site_name: My Lua Project
nav:
  - Home: index.md
  - API Reference:
    - Overview: api/index.md
    - Modules: api/modules/
    - Classes: api/classes/
  1. Build and serve:
mkdocs serve

Docusaurus Integration

# Generate docs in Docusaurus docs directory
emmylua_doc_cli ./src \
  --output ./docusaurus/docs/api \
  --site-name "MyProject API"

# Build Docusaurus site
cd docusaurus
npm run build

Custom Processing with JSON

# Generate JSON
emmylua_doc_cli ./src --output-format json --output api.json

# Process with jq
cat api.json | jq '.modules[] | {name, function_count: (.functions | length)}'

# Or use in custom build script
node generate-custom-docs.js api.json

CI/CD Documentation Pipeline

name: Generate Documentation

on:
  push:
    branches: [main]

jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install emmylua_doc
        run: cargo install emmylua_doc_cli
      
      - name: Generate documentation
        run: |
          emmylua_doc_cli ./src \
            --output ./docs \
            --site-name "${{ github.repository }} API" \
            --mixin ./doc-extras
      
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs

npm Script Integration

{
  "scripts": {
    "docs": "emmylua_doc_cli ./lua --output ./docs",
    "docs:watch": "nodemon --watch lua --exec 'npm run docs'",
    "docs:json": "emmylua_doc_cli ./lua --output-format json --output api.json",
    "docs:serve": "npm run docs && cd docs && python -m http.server"
  }
}

Advanced Usage

Custom Templates

Create a template directory structure:
templates/
├── module.md.hbs
├── class.md.hbs
├── function.md.hbs
└── partials/
    ├── parameter.hbs
    └── return.hbs
Use custom templates:
emmylua_doc_cli ./src \
  --override-template ./templates \
  --output ./docs

Mixin for Additional Content

Create a mixin directory:
doc-mixin/
├── index.md              # Custom home page
├── getting-started.md    # Tutorial
├── examples/
│   └── basic-usage.md
└── assets/
    ├── logo.png
    └── architecture.svg
Generate with mixin:
emmylua_doc_cli ./src \
  --mixin ./doc-mixin \
  --output ./docs
Result:
  • Generated API docs in ./docs
  • Custom pages from mixin included
  • Generated files overridden by mixin files if they exist

Multi-workspace Documentation

Document multiple related projects:
emmylua_doc_cli \
  ./project-core/src \
  ./project-plugins/src \
  ./project-utils/src \
  --output ./combined-docs \
  --site-name "Complete Project Documentation"

Filtered API Documentation

Generate docs only for public API:
emmylua_doc_cli ./src \
  --include "**/api/**/*.lua,**/public/**/*.lua" \
  --exclude "**/internal/**,**/*_private.lua" \
  --output ./public-api-docs

Troubleshooting

Ensure annotations are present:
--- This function won't be documented without this comment
---@param x number
---@return number
function calculate(x)
  return x * 2
end
Check file filtering:
# Use verbose mode to see which files are processed
emmylua_doc_cli ./src --verbose
Verify workspace path:
# Ensure path contains Lua files
ls -la ./src/*.lua
Check template syntax:
  • Templates use Handlebars syntax
  • Verify bracket matching: {{, }}, {{#each}}, {{/each}}
Use verbose mode:
emmylua_doc_cli ./src --override-template ./templates --verbose
Fallback to defaults:
# Generate without custom templates first
emmylua_doc_cli ./src --output ./docs
Check mixin directory structure:
# Mixin structure should mirror output structure
tree ./doc-mixin
Verify paths:
  • Mixin files use relative paths from mixin root
  • Example: mixin/index.mdoutput/index.md
Use verbose mode:
emmylua_doc_cli ./src --mixin ./doc-mixin --verbose
Check config file location:
# Config should be in workspace directory
ls -la .emmyrc.json .luarc.json
Explicitly specify config:
emmylua_doc_cli ./src --config ./.emmyrc.json --verbose
Validate JSON:
jq . .emmyrc.json

Best Practices

Write Comprehensive Annotations

--- Calculates the distance between two points
---
--- This function uses the Euclidean distance formula:
--- sqrt((x2-x1)^2 + (y2-y1)^2)
---
---@param x1 number First point X coordinate
---@param y1 number First point Y coordinate  
---@param x2 number Second point X coordinate
---@param y2 number Second point Y coordinate
---@return number distance The calculated distance
---@usage
--- local dist = distance(0, 0, 3, 4)
--- -- Result: 5.0
function distance(x1, y1, x2, y2)
    return math.sqrt((x2-x1)^2 + (y2-y1)^2)
end

Organize Documentation Structure

# Use consistent output structure
emmylua_doc_cli ./src \
  --output ./docs/api \
  --site-name "MyProject API" \
  --mixin ./docs/guides

Automate Documentation Updates

Add to your build process:
.PHONY: docs docs-watch

docs:
	emmylua_doc_cli ./src --output ./docs

docs-watch:
	watch -n 2 make docs

Version Your Documentation

# Generate versioned docs
emmylua_doc_cli ./src \
  --output ./docs/v1.2.3 \
  --site-name "MyAPI v1.2.3"

See Also

Build docs developers (and LLMs) love