Skip to main content

Overview

emmylua_check is a command-line static analysis tool that performs comprehensive code checking on Lua projects. It reports syntax errors, type mismatches, undefined variables, and other potential issues without requiring an editor.

Installation

cargo install emmylua_check

Basic Usage

emmylua_check .

Command-Line Options

Positional Arguments

WORKSPACE
path
required
One or more paths to workspace directories to analyze.
# Single workspace
emmylua_check ./src

# Multiple workspaces
emmylua_check ./src ./lib

# Current directory
emmylua_check .

Configuration Options

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

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

# Multiple config files
emmylua_check ./src --config ./config1.json,./config2.json
--ignore
string[]
Comma-separated list of glob patterns to ignore during analysis.
# Ignore single pattern
emmylua_check ./src --ignore "**/test/**"

# Ignore multiple patterns
emmylua_check ./src --ignore "**/test/**,**/build/**,**/*.spec.lua"

# Ignore node_modules and build directories
emmylua_check . --ignore "node_modules/**,build/**,dist/**"

Output Options

--output-format
string
default:"text"
Specify the output format for diagnostics.Available values:
  • text - Human-readable text format (default)
  • json - Structured JSON output
  • sarif - SARIF format (Static Analysis Results Interchange Format)
# Text output (default)
emmylua_check ./src --output-format text

# JSON output for tooling integration
emmylua_check ./src --output-format json

# SARIF output for GitHub/Azure DevOps
emmylua_check ./src --output-format sarif
--output
string
default:"stdout"
Specify output destination. Use stdout for standard output or a file path.Only used when --output-format is json or sarif.
# Output to stdout (default)
emmylua_check ./src --format json --output stdout

# Output to file
emmylua_check ./src --format json --output ./reports/check-results.json

# SARIF output to file
emmylua_check ./src --format sarif --output ./reports/results.sarif

Behavior Options

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

# Verbose mode
emmylua_check ./src --verbose
Verbose output includes:
  • File-by-file progress
  • Configuration detection details
  • Workspace loading information
  • Detailed timing information
--warnings-as-errors
boolean
Treat all warnings as errors, causing the check to fail on warnings.
# Default behavior (warnings don't fail)
emmylua_check ./src

# Strict mode (warnings cause failure)
emmylua_check ./src --warnings-as-errors
Useful for:
  • CI/CD pipelines requiring zero warnings
  • Enforcing strict code quality standards
  • Pre-commit hooks

Output Formats

Text Format (Default)

Human-readable output optimized for terminal display:
emmylua_check ./src
Example output:
Checking workspace: /home/user/project/src
Found 45 files to analyze

./src/main.lua:23:5
  error: Undefined variable 'undefindVar'
  
./src/utils.lua:15:10
  warning: Unused parameter 'options'
  
./src/api.lua:42:3
  error: Type mismatch: expected 'string', got 'number'

Analysis complete:
  Files checked: 45
  Errors: 2
  Warnings: 1
  
Check failed with 2 errors and 1 warnings

JSON Format

Structured JSON output for tooling integration:
emmylua_check ./src --format json --output results.json
Example output structure:
{
  "version": "1.0",
  "diagnostics": [
    {
      "file": "./src/main.lua",
      "line": 23,
      "column": 5,
      "severity": "error",
      "message": "Undefined variable 'undefindVar'",
      "code": "undefined-var"
    },
    {
      "file": "./src/utils.lua",
      "line": 15,
      "column": 10,
      "severity": "warning",
      "message": "Unused parameter 'options'",
      "code": "unused-parameter"
    }
  ],
  "summary": {
    "files_checked": 45,
    "errors": 2,
    "warnings": 1
  }
}

SARIF Format

SARIF (Static Analysis Results Interchange Format) for integration with GitHub, Azure DevOps, and other platforms:
emmylua_check ./src --format sarif --output results.sarif
Compatible with:
  • GitHub Code Scanning
  • Azure DevOps
  • Visual Studio
  • Other SARIF-compatible tools

Exit Codes

The tool uses exit codes to indicate the result of the analysis:
  • 0 - Success: No errors found (warnings may exist)
  • 1 - Failure: Errors detected or fatal error occurred
Note: When --warnings-as-errors is enabled, warnings also cause exit code 1.
# Check exit code
emmylua_check ./src
echo $?  # 0 = success, 1 = errors found

# Use in scripts
if emmylua_check ./src; then
  echo "Check passed"
else
  echo "Check failed"
  exit 1
fi

# CI/CD usage
emmylua_check ./src || exit 1

CI/CD Integration

GitHub Actions

name: Lua Static Analysis

on: [push, pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install emmylua_check
        run: cargo install emmylua_check
      
      - name: Run static analysis
        run: emmylua_check ./src --format sarif --output results.sarif
      
      - name: Upload SARIF results
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: results.sarif

GitLab CI

lua_check:
  stage: test
  image: rust:latest
  before_script:
    - cargo install emmylua_check
  script:
    - emmylua_check ./src --format json --output check-results.json
  artifacts:
    reports:
      codequality: check-results.json
    when: always

Azure Pipelines

- task: Bash@3
  displayName: 'Install emmylua_check'
  inputs:
    targetType: 'inline'
    script: 'cargo install emmylua_check'

- task: Bash@3
  displayName: 'Run Static Analysis'
  inputs:
    targetType: 'inline'
    script: |
      emmylua_check ./src --format sarif --output $(Build.ArtifactStagingDirectory)/results.sarif
  continueOnError: false

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: 'CodeAnalysis'

Jenkins

pipeline {
    agent any
    
    stages {
        stage('Static Analysis') {
            steps {
                sh 'cargo install emmylua_check'
                sh 'emmylua_check ./src --format json --output check-results.json'
            }
        }
    }
    
    post {
        always {
            archiveArtifacts artifacts: 'check-results.json', allowEmptyArchive: true
        }
    }
}

Common Workflows

Pre-commit Hook

Add to .git/hooks/pre-commit:
#!/bin/bash

echo "Running Lua static analysis..."

if ! emmylua_check ./src --warnings-as-errors; then
    echo "Static analysis failed. Please fix the errors before committing."
    exit 1
fi

echo "Static analysis passed!"
Make it executable:
chmod +x .git/hooks/pre-commit

Make Target

Add to your Makefile:
.PHONY: check check-strict check-json

check:
	emmylua_check ./src

check-strict:
	emmylua_check ./src --warnings-as-errors

check-json:
	emmylua_check ./src --format json --output check-results.json
	@cat check-results.json | jq '.summary'
Usage:
make check          # Regular check
make check-strict   # Strict mode
make check-json     # JSON output with summary

npm/package.json Script

{
  "scripts": {
    "lint:lua": "emmylua_check ./lua",
    "lint:lua:strict": "emmylua_check ./lua --warnings-as-errors",
    "lint:lua:ci": "emmylua_check ./lua --format sarif --output results.sarif"
  }
}
Usage:
npm run lint:lua          # Regular check
npm run lint:lua:strict   # Strict mode
npm run lint:lua:ci       # CI format

Advanced Usage

Large Codebases

For large projects, optimize performance with ignore patterns:
emmylua_check ./src \
  --ignore "**/node_modules/**,**/vendor/**,**/build/**,**/.git/**" \
  --verbose

Multi-project Monorepos

Analyze multiple independent projects:
# Analyze each project separately
emmylua_check ./packages/core ./packages/utils ./packages/api

# With individual configs
emmylua_check ./packages/core --config ./packages/core/.emmyrc.json
emmylua_check ./packages/utils --config ./packages/utils/.emmyrc.json

Custom Configuration

Create .emmyrc.json in your workspace:
{
  "diagnostics": {
    "severity": {
      "undefined-global": "error",
      "unused-local": "warning",
      "trailing-space": "hint"
    },
    "disable": ["lowercase-global"]
  },
  "workspace": {
    "library": ["./lib"],
    "ignoreDir": ["build", "temp"]
  }
}

Integration with Other Tools

# Get only errors (JSON output)
emmylua_check ./src --format json | jq '.diagnostics[] | select(.severity == "error")'

# Count diagnostics by severity
emmylua_check ./src --format json | jq '.diagnostics | group_by(.severity) | map({severity: .[0].severity, count: length})'

Troubleshooting

Check workspace path:
# Verify directory exists and contains Lua files
ls -la ./src/*.lua

# Use verbose mode to see what's happening
emmylua_check ./src --verbose
Check ignore patterns:
  • Ensure ignore patterns aren’t excluding all files
  • Review .emmyrc.json configuration
Verify config file location:
# Check for config files
ls -la .emmyrc.json .emmyrc.lua .luarc.json

# Explicitly specify config
emmylua_check ./src --config ./.emmyrc.json --verbose
Validate JSON syntax:
# Use jq to validate JSON
jq . .emmyrc.json
Adjust diagnostic severity:Create or modify .emmyrc.json:
{
  "diagnostics": {
    "disable": ["unused-local", "trailing-space"],
    "severity": {
      "undefined-global": "warning"
    }
  }
}
Add type annotations:
  • Use EmmyLua annotations to provide type information
  • This reduces false positives significantly
Optimize with ignore patterns:
emmylua_check ./src --ignore "**/node_modules/**,**/build/**"
Analyze specific directories:
# Instead of checking everything
emmylua_check ./src ./lib
Use multiple processes:
# Split analysis across directories
emmylua_check ./src &
emmylua_check ./lib &
wait

See Also

Build docs developers (and LLMs) love