# zigtools/zls: a Zig language server for editor autocomplete and goto definition

> ZLS is a non-official Language Server Protocol implementation for Zig, written in Zig. It gives editors completions, hover, diagnostics, formatting and rename, but it must be kept in step with the Zig version you build against.

**zigtools/zls** — A language server for Zig supporting developers with features like autocomplete and goto definition

- Repository: https://github.com/zigtools/zls
- Website: https://zigtools.org/zls/install/
- Stars: 5,151 · Forks: 451
- Language: Zig
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/zigtools-zls

## The gap zls fills between zig and your editor

Zig ships a compiler and a formatter, not an editor integration. Without a language server, an editor sees Zig source as plain text: no completion list, no jump to a declaration, no inline diagnostics until you run `zig build` yourself. ZLS is the process that closes that gap. It is a non-official implementation of the Language Server Protocol for Zig, written in Zig, and it exists so that any editor with an LSP client can get IDE features without each editor team writing its own Zig front end.

The audience is narrow and specific. If you write Zig in Neovim, VS Code, Zed, Helix or Emacs and your editor already has an LSP client, ZLS is the piece you plug in. If you only compile Zig occasionally from a terminal, the server adds a background process and a version-matching obligation for features you will not use.

## What the server actually does with your project

ZLS speaks LSP over stdio to the editor and holds its own view of the source tree. The README lists the supported surface: completions, hover, diagnostics, go to definition and declaration, workspace and document symbols, find references, rename symbol, formatting based on `zig fmt`, semantic tokens highlighting, inlay hints and code actions. Those are the requests an editor forwards once it has started the server for a `.zig` file.

The README is explicit about where the depth stops. It says ZLS supports "most language features, including simple type function support, payload capture type resolution, custom packages", and then states that support for comptime and semantic analysis is work in progress. That sentence matters more than the feature list. Zig pushes a lot of work into compile time, so a server that resolves types through ordinary declarations but not through arbitrary comptime evaluation will sometimes show a completion or a definition that the compiler later rejects, or fail to resolve something the compiler handles fine. Diagnostics from ZLS are a convenience layer, not a verdict.

Build-on-save is opt-in rather than default. The README links a dedicated guide for it, which is the right shape: running the build system on every save is a choice with a real cost on large projects, and ZLS does not make it for you.

## Installing zls and getting a first completion

The README does not inline installation steps. It points at the Zigtools website, saying the complete installation guide there covers editor setup, prebuilt binaries and additional documentation. Start from that page and pick either a prebuilt binary for your platform or a source build.

Building from source is documented in the README as a clone plus a Zig build invocation:

```bash
cd zls
git clone https://github.com/zigtools/zls
cd zls
zig build -Doptimize=ReleaseSafe
```

The build produces the server binary; the README does not spell out the output path, so check what `zig build` reports for your target. Note the warning printed directly above those instructions: ZLS currently lacks critical build system integration with Zig nightly/master, and the README recommends using Zig and ZLS 0.16.0 in the meantime. The default branch targets Zig master.

Once you have a binary, point your editor's LSP client at it and open a Zig file in a project that has a `build.zig`. The first thing to confirm is that the server started at all: most clients expose a log or a status entry for the running server. Then trigger completion inside a function body and jump to a declaration from another file in the same package. If completion works but cross-file goto definition does not, the usual cause is that the server has not resolved the project's package structure, which is where the README's mention of custom packages becomes relevant.

## Version drift is the failure mode to plan for

The README's own upgrade instruction is blunt: when upgrading Zig, make sure to update ZLS too, to keep them in sync. This is the constraint that shapes daily use. ZLS parses and reasons about Zig source, and the language changes; a server built against one Zig release may misread syntax or stdlib shapes from another. The README's recommendation to pair Zig with ZLS 0.16.0 exists precisely because the default branch tracks Zig master instead of a stable release.

So the practical failure is not a crash. It is quiet wrongness: a diagnostic that no longer applies, a symbol that resolves to the wrong declaration, completion that stops offering standard library items after a toolchain bump. On a team where one developer upgrades Zig and another does not, the same file can produce different editor output on two machines while `zig build` agrees on both. If you cannot pin both versions together, ZLS is the wrong tool and running the compiler is the honest alternative.

## zls compared with ZLS alternatives and editor built-ins

The realistic comparison is not another language server for Zig, because the README presents ZLS as the non-official LSP implementation for the language. The comparison is against what your editor gives you without it.

A plain editor with no LSP client gives you syntax highlighting and nothing semantic. That is a legitimate setup: it never goes stale, never consumes memory in the background, and never disagrees with the compiler. What you lose is navigation in a codebase where a symbol is defined in a file you have not opened, and the completion list that shortens stdlib names you half remember.

A second comparison is against running `zig fmt` and `zig build` as explicit commands rather than through the server. Formatting through ZLS is documented as being based on `zig fmt`, so the output should match the command line tool, but the command line version has no version-matching problem with the server binary because it is the same binary as the compiler. Teams that already run formatting and builds in CI can treat the editor integration as a convenience rather than a source of truth, which removes most of the risk described above.

## Licence, maintenance and what an upgrade costs

ZLS is MIT licensed. That is permissive: you can bundle the binary, ship it inside a company toolchain image, or fork it, provided you keep the licence text. This is not legal advice, and if you redistribute a modified build, read the LICENSE file in the repository rather than a summary.

The repository is not archived, and the last push was on 2026-09-11. Releases are infrequent and versioned against Zig: 0.15.0 in August 2025, 0.15.1 in December 2025, and 0.16.0 in April 2026. That cadence follows the compiler rather than a fixed schedule, so an upgrade is not a routine dependency bump. It is a paired change: new Zig, new ZLS, then re-check that your editor still starts the server and that build-on-save, if you enabled it, still behaves. Budget for that pairing rather than treating the server as a background tool that updates itself.

## Conclusion

Adopt zls if you write Zig in an editor that already speaks LSP and you are willing to keep the server and the compiler on matching versions; the README recommends Zig and ZLS 0.16.0 together and warns that the default branch targets Zig master. Do not adopt it expecting finished comptime and semantic analysis, which the README labels work in progress, and do not treat it as a substitute for the compiler. Before wiring it into a team setup, verify which Zig release your toolchain pins, check that a prebuilt binary exists for your platform on the install page, and confirm the build-on-save guide matches the diagnostics behaviour you want.

## FAQ

### What does ZLS mean?

ZLS is the name of the project, described in its README as a non-official implementation of the Language Server Protocol for Zig, written in Zig. It provides IDE features in your editor.

### What is Zig used for?

The README does not describe Zig itself; it only says ZLS is a language server for Zig and that the default branch targets Zig master. Zig is the language whose files the server reads to provide completions, hover, diagnostics and navigation.

### What are the disadvantages of Zig?

The README does not discuss disadvantages of the Zig language. The closest project-level constraint it states is that ZLS currently lacks critical build system integration with Zig nightly/master, and that Zig and ZLS should be updated together to stay in sync.

### What companies use Zig?

The README does not name any companies using Zig. It only credits contributors, donators, backers and sponsors of the ZLS project itself.

## Sources

- [License: MIT](https://github.com/zigtools/zls/blob/master/LICENSE)
- [Project website](https://zigtools.org/zls/install/)
- [README](https://github.com/zigtools/zls/blob/master/README.md)
- [Releases](https://github.com/zigtools/zls/releases)
- [zigtools/zls on GitHub](https://github.com/zigtools/zls)

---

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