EmmyLua Configuration Guide
May 18, 2026 · View on GitHub
EmmyLua Analyzer Rust recommends keeping project configuration in .emmyrc.json at the workspace root.
Supported config files:
.emmyrc.json: recommended, full feature support.luarc.json: useful when migrating from existing LuaLS setups.emmyrc.lua: useful for dynamically generated config
Quick Start
Put this minimal config in your project root:
{
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
"runtime": {
"version": "LuaLatest"
},
"workspace": {
"workspaceRoots": ["./src"]
}
}
Schema Support
Adding $schema gives you:
- config completion
- field validation
- enum suggestions
- hover descriptions
{
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json"
}
Path Rules
Paths in workspace and resource are expanded automatically when config is loaded.
| Syntax | Meaning |
|---|---|
./libs | Relative to the workspace root |
libs/runtime | Also treated as workspace-relative |
~/lua | Relative to the user home directory |
${workspaceFolder} or {workspaceFolder} | Workspace root |
{env:NAME} | Environment variable NAME |
$NAME | Environment variable NAME |
{luarocks} | LuaRocks deploy lua directory |
Example:
{
"workspace": {
"library": [
"${workspaceFolder}/types",
"{env:HOME}/.lua",
"{luarocks}"
],
"workspaceRoots": [
"./src",
"./test"
]
}
}
Recommended Template
This template is a good starting point for most Lua projects:
{
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
"completion": {
"autoRequire": true,
"callSnippet": false,
"postfix": "@"
},
"diagnostics": {
"globals": [],
"disable": ["undefined-global"]
},
"doc": {
"syntax": "md"
},
"runtime": {
"version": "LuaLatest",
"requirePattern": ["?.lua", "?/init.lua"]
}
}
Full Configuration Example
Note: the current top-level formatting key is
format, notreformat.
Click to expand the full example
{
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
"codeAction": {
"insertSpace": null
},
"codeLens": {
"enable": true
},
"completion": {
"enable": true,
"autoRequire": true,
"autoRequireFunction": "require",
"autoRequireNamingConvention": "keep",
"autoRequireSeparator": ".",
"callSnippet": false,
"postfix": "@",
"baseFunctionIncludesName": true
},
"diagnostics": {
"enable": true,
"disable": [],
"enables": [],
"globals": [],
"globalsRegex": [],
"severity": {},
"diagnosticInterval": 500
},
"doc": {
"privateName": [],
"knownTags": [],
"syntax": "md"
},
"documentColor": {
"enable": true
},
"format": {
"externalTool": null,
"externalToolRangeFormat": null,
"useDiff": false
},
"hint": {
"enable": true,
"paramHint": true,
"indexHint": true,
"localHint": true,
"overrideHint": true,
"metaCallHint": true,
"enumParamHint": false
},
"hover": {
"enable": true,
"customDetail": null
},
"inlineValues": {
"enable": true
},
"references": {
"enable": true,
"fuzzySearch": true,
"shortStringSearch": false
},
"resource": {
"paths": []
},
"runtime": {
"version": "LuaLatest",
"requireLikeFunction": [],
"frameworkVersions": [],
"extensions": [],
"requirePattern": [],
"nonstandardSymbol": [],
"special": {}
},
"semanticTokens": {
"enable": true,
"renderDocumentationMarkup": true
},
"signature": {
"detailSignatureHelper": true
},
"strict": {
"requirePath": false,
"typeCall": false,
"arrayIndex": true,
"metaOverrideFileDefine": true,
"docBaseConstMatchBaseType": true,
"requireExportGlobal": false
},
"workspace": {
"ignoreDir": [],
"ignoreGlobs": [],
"library": [],
"packageDirs": [],
"workspaceRoots": [],
"preloadFileSize": 0,
"encoding": "utf-8",
"moduleMap": [],
"reindexDuration": 5000,
"enableReindex": false
}
}
Top-Level Overview
| Section | Purpose | Common fields |
|---|---|---|
completion | Completion and auto-require | autoRequire, callSnippet, postfix |
diagnostics | Diagnostic toggles, allowlists, severity overrides | disable, globals, severity |
doc | Documentation parsing and rendering | syntax, knownTags, privateName |
runtime | Lua version, extra syntax, require behavior | version, extensions, requirePattern |
workspace | Roots, libraries, ignore rules | library, workspaceRoots, ignoreGlobs |
strict | Stricter typing and visibility rules | arrayIndex, requireExportGlobal |
format | External formatter integration | externalTool, externalToolRangeFormat |
hint | Inlay hints | paramHint, localHint, enumParamHint |
hover | Hover information | enable, customDetail |
references | Reference search behavior | fuzzySearch, shortStringSearch |
Configuration Reference
completion
| Field | Type | Default | Description |
|---|---|---|---|
enable | boolean | true | Enable completion |
autoRequire | boolean | true | Insert require automatically for symbols from other modules |
autoRequireFunction | string | "require" | Function name used for auto-require |
autoRequireNamingConvention | string | "keep" | Filename conversion mode: keep, snake-case, pascal-case, camel-case, keep-class |
autoRequireSeparator | string | "." | Separator used in auto-require paths |
callSnippet | boolean | false | Include call snippets in function completion |
postfix | string | "@" | Postfix completion trigger |
baseFunctionIncludesName | boolean | true | Include the function name when generating base function snippets |
diagnostics
| Field | Type | Default | Description |
|---|---|---|---|
enable | boolean | true | Enable diagnostics |
disable | string[] | [] | Disabled diagnostic rules |
enables | string[] | [] | Additional rules to enable |
globals | string[] | [] | Global variable allowlist |
globalsRegex | string[] | [] | Regex allowlist for global variables |
severity | object | {} | Per-rule severity overrides |
diagnosticInterval | `number | null` | 500 |
Supported severities: error, warning, information, hint.
Example:
{
"diagnostics": {
"disable": ["undefined-global"],
"severity": {
"undefined-global": "warning",
"unused": "hint"
},
"enables": ["unknown-doc-tag"]
}
}
Show diagnostic rules
Default error rules:
syntax-errordoc-syntax-errorundefined-globallocal-const-reassignannotation-usage-erroriter-variable-reassign(enabled by default on Lua 5.5+)
Default hint rules:
unreachable-codeunuseddeprecatedredefined-localduplicate-requirepreferred-local-alias
Disabled by default:
code-style-checkincomplete-signature-docmissing-global-docunknown-doc-tagnon-literal-expressions-in-assert
All remaining built-in rules default to warning:
type-not-foundmissing-returnparam-type-mismatchmissing-parameterredundant-parameteraccess-invisiblediscard-returnsundefined-fieldduplicate-typeredefined-labelneed-check-nilawait-in-syncreturn-type-mismatchmissing-return-valueredundant-return-valueundefined-doc-paramduplicate-doc-fieldmissing-fieldsinject-fieldcircle-doc-classassign-type-mismatchunbalanced-assignmentsunnecessary-assertunnecessary-ifduplicate-set-fieldduplicate-indexgeneric-constraint-mismatchcast-type-mismatchunresolved-requirerequire-module-not-visibleenum-value-mismatchread-onlyglobal-in-non-moduleattribute-param-type-mismatchattribute-missing-parameterattribute-redundant-parameterinvert-ifcall-non-callable
doc
| Field | Type | Default | Description |
|---|---|---|---|
privateName | string[] | [] | Treat matching field names as private members, for example m_* |
knownTags | string[] | [] | Additional documentation tags to recognize |
syntax | string | "md" | Documentation syntax: none, md, myst, rst |
rstPrimaryDomain | `string | null` | null |
rstDefaultRole | `string | null` | null |
runtime
| Field | Type | Default | Description |
|---|---|---|---|
version | string | "LuaLatest" | Lua version: Lua5.1, LuaJIT, Lua5.2, Lua5.3, Lua5.4, Lua5.5, LuaLatest |
requireLikeFunction | string[] | [] | Function names treated like require |
frameworkVersions | string[] | [] | Framework version identifiers |
extensions | string[] | [] | Additional file extensions treated as Lua |
requirePattern | string[] | [] | Module search patterns such as ?.lua and ?/init.lua |
nonstandardSymbol | string[] | [] | Allowed non-standard syntax symbols |
special | object | {} | Special function mappings |
Supported nonstandardSymbol values:
///**/`+=-=*=/=%=^=//=|=&=<<=>>=||&&!!=continue
Supported special values: none, require, error, assert, type, setmetatable.
workspace
| Field | Type | Default | Description |
|---|---|---|---|
ignoreDir | string[] | [] | Ignored directories |
ignoreGlobs | string[] | [] | Glob patterns to ignore |
library | string[] | object[] | [] |
packages | string[] | object[] | [] |
workspaceRoots | string[] | [] | Workspace source roots |
preloadFileSize | number | 0 | Reserved field, currently unused |
encoding | string | "utf-8" | File encoding |
moduleMap | object[] | [] | Module name rewrite rules |
reindexDuration | number | 5000 | Delay before full reindex, in milliseconds |
enableReindex | boolean | false | Enable full reindex after file changes |
library and packages can be either a string path or an object:
{
"workspace": {
"library": [
"./types",
{
"path": "./vendor",
"ignoreDir": ["test"],
"ignoreGlobs": ["**/*.spec.lua"]
}
]
}
}
moduleMap example:
{
"workspace": {
"moduleMap": [
{
"pattern": "^lib(.*)$",
"replace": "script\$1"
}
]
}
}
strict
| Field | Type | Default | Description |
|---|---|---|---|
requirePath | boolean | false | Require import paths must match configured module paths |
typeCall | boolean | false | Apply stricter checking to type calls |
arrayIndex | boolean | true | Apply stricter array index checks |
metaOverrideFileDefine | boolean | true | Meta definitions override file-local definitions |
docBaseConstMatchBaseType | boolean | true | Allow base constant doc types to match base scalar types |
requireExportGlobal | boolean | false | Third-party libraries must use ---@export global before they become importable |
format
For more details, see External Formatter Options.
| Field | Type | Default | Description |
|---|---|---|---|
externalTool | `object | null` | null |
externalToolRangeFormat | `object | null` | null |
useDiff | boolean | false | Merge formatter output through a diff step |
External tool object:
| Field | Type | Default | Description |
|---|---|---|---|
program | string | "" | Executable to run |
args | string[] | [] | Argument list |
timeout | number | 5000 | Timeout in milliseconds |
Other sections
| Section | Field | Default | Description |
|---|---|---|---|
codeAction | insertSpace | null | Override formatter emmy_doc.space_between_tag_columns when inserting @diagnostic disable-next-line |
codeLens | enable | true | Enable CodeLens |
documentColor | enable | true | Detect color-like strings and show color previews |
hint | enable | true | Master switch |
hint | paramHint | true | Parameter name and parameter type hints |
hint | indexHint | true | Named array index hints |
hint | localHint | true | Local variable type hints |
hint | overrideHint | true | Override hints |
hint | metaCallHint | true | Hints for metatable __call dispatch |
hint | enumParamHint | false | Enum literal hints |
hover | enable | true | Enable hover docs |
hover | customDetail | null | Custom hover detail level, typically 1 to 255 |
inlineValues | enable | true | Show inline values during debugging |
references | enable | true | Enable reference search |
references | fuzzySearch | true | Fall back to fuzzy matching when normal search finds nothing |
references | shortStringSearch | false | Also search inside short strings |
resource | paths | [] | Resource roots for path completion and navigation |
semanticTokens | enable | true | Enable semantic highlighting |
semanticTokens | renderDocumentationMarkup | true | Render documentation markup, used together with doc.syntax |
signature | detailSignatureHelper | true | Show detailed signature help |
Recommendations
- Prefer
.emmyrc.jsonfor new projects - When migrating from LuaLS, keep
.luarc.jsonfirst and move to.emmyrc.jsongradually - Configure
workspace.libraryandworkspace.workspaceRootsearly, otherwise navigation, completion, and diagnostics will be less precise - If your team uses custom doc tags, remember to add them to
doc.knownTags - If you want stricter third-party library visibility, consider enabling
strict.requireExportGlobal