# Luau LSP: a language server for Roblox's Luau with Rojo sourcemap resolution

> luau-lsp is an MIT-licensed language server for Luau that resolves Roblox DataModel instances through Rojo-generated sourcemaps, ships a standalone analyze mode for CI, and implements most of the LSP specification with a documented list of what it leaves out. It suits a Roblox developer working across a Rojo project, and its DataModel typing is deliberately loose in diagnostics.

**JohnnyMorganz/luau-lsp** — Language Server Implementation for Luau

- Repository: https://github.com/JohnnyMorganz/luau-lsp
- Stars: 557 · Forks: 157
- Language: Luau
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/johnnymorganz-luau-lsp

## What the project is, and how you install it

luau-lsp is an implementation of a language server for the Luau programming language, and Luau is the language Roblox uses, derived from Lua.

The installation path for most people is a browser extension rather than a binary. The extension is published on the VSCode Marketplace and on the OpenVSX Registry, which is the registry that non-VSCode editors use, so an editor built on the Open VSX platform gets the same extension. For anything else, the project points at a document called Getting Started for Language Server Clients, in the editors/ directory of the repository, which covers wiring the server into a different editor.

There is also a nightly release that runs every day with the latest changes on main, and you can download the relevant artefact for your platform and install the .vsix manually. The nightly build is compiled with debug symbols and profiling instrumentation for debugging, which is why it is worth having even if you would normally stay on a stable release: the instrumentation is what makes a performance question answerable.

For general users, the documentation says the language server will start working immediately for general Luau code, and there is built-in support for Luau's generalised require-by-string semantics, using require("./module"). That last point is a real convenience, because a project that uses the newer require form works without the server having to be taught about a custom resolution table.

The project is MIT licensed, the primary language is Luau, the default branch is main, and the recent releases are 1.70.1 from 2026-09-27, 1.70.0 from 2026-09-20 and 1.69.0 from 2026-07-18, with the last push to the repository on 2026-10-17. The repository is a C++ project with a CMakeLists.txt, .clang-format and .clang-tidy, an extern/ directory for vendored dependencies, a luau/ directory, an editors/ directory for the client guides, a plugin/ directory for the Studio companion, and formatting and linting configuration for StyLua and Selene.

## Rojo sourcemaps, and why they are the crux

The part of this project that makes it more than a Lua language server is the Rojo integration, and it is worth understanding what problem it solves.

The Roblox DataModel is a tree of Instances, and your Luau source files describe parts of that tree. A static type checker reading a source file has no idea what the instance hierarchy is, so the type of a value that comes from a parent instance is unknown. A sourcemap is the file that connects the two, mapping between the DataModel tree and the files on disk.

For Rojo users the requirement is version 7.3.0 or newer, and by default the latest Roblox type definitions and documentation are preloaded out of the box. That can be disabled by configuring luau-lsp.platform.type.

The mechanism is a running command. The language server uses Rojo-style sourcemaps to resolve DataModel instance trees for intellisense, and it is done by running:

```bash
rojo sourcemap --watch default.project.json --output sourcemap.json
```

The server listens to changes of a sourcemap.json file present at the workspace root, and the documentation recommends adding that file to your .gitignore, which is sensible because it is generated output that changes constantly.

Five settings control the generation, and they are all documented with their defaults: luau-lsp.sourcemap.enabled for whether sourcemap support is on, which is on by default; luau-lsp.sourcemap.autogenerate for whether sourcemaps are automatically generated by the client, also on by default, and if it is disabled the server listens for manual changes to sourcemap.json; luau-lsp.sourcemap.rojoProjectFile for the project file, defaulting to default.project.json; luau-lsp.sourcemap.includeNonScripts for whether non script instances are included, on by default and disableable for expensive DataModels; and luau-lsp.sourcemap.sourcemapFile, defaulting to sourcemap.json.

If you do not use Rojo, you can still use the language server, and the documentation is clear that you just need to generate a sourcemap.json file manually for your particular project layout. You can configure luau-lsp.sourcemap.generatorCommand to run a custom generator, and if your generator does not support file watching, you enable luau-lsp.sourcemap.useVSCodeWatcher.

## The DataModel typing limitation, stated plainly

The documentation includes a note that is unusual to find and worth reading in full, because it describes a deliberate trade rather than a bug.

In the diagnostics type checker, the types for DataModel instances resolve to any. This is a current limitation to reduce false positives. Autocomplete and hover intellisense will correctly resolve the DM type. To enable the stricter mode for diagnostics, set luau-lsp.diagnostics.strictDatamodelTypes, which is off by default.

The reasoning is sound. A DataModel instance can be created at runtime, can be renamed, can come from a server call, and can be any of a large number of types depending on how the tree was assembled. A type checker that insisted on the precise type would produce a stream of false errors in a real project, and a developer who turns off the diagnostics because it is noisy turns off all of them, including the ones that matter. Resolving to any in diagnostics keeps the error list trustworthy, at the price of not catching the case where a method is called on the wrong kind of instance.

The split is what makes the compromise tolerable. The information is still there, in the editor, where the developer is looking at it anyway. The check that would produce false positives is where the precision is dropped.

There is also a companion plugin for Roblox Studio, published on the Plugin Marketplace, which provides DataModel information for Instances that are not part of your Rojo build or filetree. That is the escape hatch for the case where a project has content authored in Studio, and the annotation is that this information comes from the running editor rather than from the sourcemap.

The strict mode is documented with a link to an issue comment explaining it, which is a good sign, because it means the default can be revisited with the reasoning in public.

## Standalone mode for CI, and the two configuration systems

The tool can run standalone, similar to luau-analyze, to provide type and lint warnings in CI, with full Rojo resolution and API types support. The entry point is luau-lsp analyze, and the documentation tells you to install the binary and run luau-lsp --help for more information.

That is the feature that makes the server usable in a pipeline. The interesting part is the phrase with full Rojo resolution and API types support, because a CI job that only checked plain Luau would be checking a fraction of the code. Resolving the DataModel in CI means the same warnings appear in a pull request check that a developer sees in the editor.

Configuration comes in two styles, and the distinction is useful. General configuration is provided by .luaurc files, which allow you to configure language strictness, lints and require aliases, and the documentation points at Luau's RFC documentation for the format. The second configuration style is specific to the language server, and you see it as luau-lsp in your editor's settings.

The split follows the audience. The .luaurc file belongs in version control and applies to every tool that reads Luau configuration, including the Roblox runtime and the linter, so strictness decisions are made once. The luau-lsp settings are editor-level and cover the sourcemap wiring and the diagnostics options that are specific to the server.

For a custom environment that is not Roblox, the general user documentation says to specify luau-lsp.types.definitionFiles to provide global type definitions, with the corresponding documentation configured using luau-lsp.types.documentationFiles, and to get in touch if you use Luau in a different environment and are interested in the language server.

## Feature coverage, crash reporting and building from source

The supported features list is long and mostly ticked: diagnostics including type errors, autocompletion, hover, signature help, go to definition, go to type definition, find references, document link, document symbol, a color provider, rename, semantic tokens, inlay hints, documentation comments in the Moonwave style supporting both the --- comment and the long --[=[ comment ]=] form but which must be next to a statement, code actions, workspace symbols, folding range and call hierarchy.

The unticked list is the more interesting half, because each entry has a reason next to it. Go to Declaration and Go To Implementation are marked as not applying, code lens and document highlight as not necessary, selection range as not necessary because editor selection is sufficient, inline value as applying to debuggers only, and moniker as simply listed. Two have explanations that matter for Luau specifically: formatting is not implemented and the project points you at StyLua, and type hierarchy is not implemented because Luau currently does not provide any public ways to define type hierarchies.

That last entry is a good sign of how the project is run. The author has thought about which parts of the LSP specification are relevant to the language rather than implementing the specification and letting the irrelevant parts be empty.

Crash reporting is opt-in and uses Sentry. On VSCode it is configured with the setting luau-lsp.server.crashReporting.enabled, and when a crash is encountered an out-of-process crash handler uploads the crash details to Sentry over HTTP. The report stores the crash reason and the thread stack trace, the device metadata of OS name, version and CPU architecture, and the dynamic libraries loaded into the process including their filesystem paths. That information is transferred through a Minidump file, and the file is not stored after processing. No general usage data is recorded. Crash reporting is only available for Windows and macOS, and it is not active for the standalone analyze mode.

The detail about dynamic libraries and filesystem paths is the one to weigh, because a path list can reveal the shape of a development machine and a build layout, and it goes to a third party. It is opt-in and the documentation is explicit, which is the correct way to do it, but it is a setting to make deliberately.

Building from source needs submodules, and the documentation says to use --recurse-submodules when you initially clone the project:

```bash
git clone https://github.com/JohnnyMorganz/luau-lsp.git --recurse-submodules
```

The repository also carries an aftman.toml, which is the toolchain manager Roblox developers use for Luau tooling, and a .stylua.toml and selene.toml for formatting and linting, so the project uses the same tools as the rest of the Luau ecosystem.

## Conclusion

Luau LSP is worth installing if you write Roblox code in a Rojo project, because the sourcemap integration is the piece that makes DataModel-aware intellisense possible at all, because the standalone analyze mode gives you the same type checking in CI that you get in the editor, and because the server is published nightly so a bug fix reaches you in a day rather than at the next release. It is the wrong tool if you are on a plain Luau project with no DataModel, and it is the wrong tool if you want strict DataModel typing in diagnostics today. Before you adopt it, check three things: that your Rojo is version 7.3.0 or newer, since that is the stated requirement for the preloaded Roblox type definitions, and that you generate a sourcemap and add it to your .gitignore, because the server watches the sourcemap.json file at the workspace root; that you accept the documented typing limitation, since the types for DataModel instances resolve to any in the diagnostics type checker to reduce false positives, while autocomplete and hover resolve them correctly, and the strict mode is behind luau-lsp.diagnostics.strictDatamodelTypes which is off by default; and that you decide about crash reporting explicitly, because it is opt-in and sends the crash reason, the device metadata and the list of loaded dynamic libraries to Sentry, which is a lot of detail to upload by accident.

## FAQ

### How do I install the Luau language server?

Install the extension from the VSCode Marketplace or from the OpenVSX Registry, which is the registry used by editors other than VSCode. For another editor, follow the Getting Started for Language Server Clients guide in the repository's editors/ directory. A nightly build with the latest changes on main is also published every day and can be installed manually as a .vsix, and it is built with debug symbols and profiling instrumentation.

### How does luau-lsp resolve Roblox DataModel types?

It uses Rojo-style sourcemaps. With Rojo 7.3.0 or newer you run rojo sourcemap --watch default.project.json --output sourcemap.json, and the server listens for changes to the sourcemap.json file at the workspace root, which the documentation recommends adding to your .gitignore. If you do not use Rojo you can generate that file with your own tool and point the server at it with luau-lsp.sourcemap.generatorCommand.

### Can luau-lsp be used to check Luau code in CI?

Yes. The tool can run standalone, similar to luau-analyze, to provide type and lint warnings in CI with full Rojo resolution and API types support, and the entry point is luau-lsp analyze. The same command is available as a binary you install, with luau-lsp --help giving the details.

## Sources

- [Issues](https://github.com/JohnnyMorganz/luau-lsp/issues)
- [JohnnyMorganz/luau-lsp on GitHub](https://github.com/JohnnyMorganz/luau-lsp)
- [License: MIT](https://github.com/JohnnyMorganz/luau-lsp/blob/main/LICENSE)
- [README](https://github.com/JohnnyMorganz/luau-lsp/blob/main/README.md)
- [Releases](https://github.com/JohnnyMorganz/luau-lsp/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/johnnymorganz-luau-lsp
