Visual Studio Code Icon

VS Code users only need the official Zig Language extension.

No need to manually install Zig or ZLS.

Install Editor Extension

Many editor extensions can find Zig and ZLS automatically by adding them to your PATH.

Visual Studio Code

Using ZLS in VS Code is as simple as installing the official Zig Language extension. (open in VSCode, open in VSCodium)

Sublime Text

  1. install the LSP and sublime-zig-language package (Package Control Usage)
  2. place the following snippet in the LSP.sublime-settings (Preferences -> Package Settings -> LSP -> Settings)
  3. place the following snippet in the Zig.sublime-settings (Preferences -> Package Settings -> Zig -> Settings)

show Zig.sublime-settings

// Zig.sublime-settings
{
  // ZLS will run format on save
  "zig.fmt.on_save": false,
  // automatically hide the build/fmt output panel
  "zig.quiet": true
}

Sublime Text 4

show LSP.sublime-settings

// LSP.sublime-settings
{
  // General settings
  // Keep in mind that these settings apply to any language and not just Zig.

  // ZLS uses `zig fmt` as the formatter.
  // The Zig FAQ answers some questions about `zig fmt`:
  // https://github.com/ziglang/zig/wiki/FAQ
  "lsp_format_on_save": true,
  "lsp_code_actions_on_save": {
    // Enable code actions that currently supports adding and removing discards.
    "source.fixAll": true
  },
  // Show inlay hints in the editor. Inlay hints are short annotations within the code,
  // which show variable types or parameter names.
  "show_inlay_hints": true,
  "semantic_highlighting": true,

  "clients": {
    "zig": {
      // Enable or disable this client configuration.
      "enabled": true,
      // The command line required to run the server.
      "command": ["/path/to/zls_executable"],
      "selector": "source.zig",
      // There are two ways to set config options:
      //   - edit your `zls.json` that applies to any editor that uses ZLS
      //   - set in-editor config options with the `settings` field below.
      //
      // Further information on how to configure ZLS:
      // https://github.com/zigtools/zls/wiki/Configuration
      "settings": {
        // Whether to enable build-on-save diagnostics
        // "enable_build_on_save": true,

        // omit the following line if `zig` is in your PATH
        "zig_exe_path": "/path/to/zig_executable"
      }
    }
  }
}

Sublime Text 3

show LSP.sublime-settings

// LSP.sublime-settings
{
  "clients": {
    "zig": {
      "command": ["/path/to/zls_executable"],
      "enabled": true,
      "languageId": "zig",
      "scopes": ["source.zig"],
      "syntaxes": ["Packages/Zig Language/Syntaxes/Zig.tmLanguage"]
    }
  }
}

CLion / other JetBrains IDEs

  • Install the ZigBrains plugin from the marketplace
  • Restart the IDE (necessary for the plugin to integrate itself correctly)

If you have both zig and zls on $PATH, then the plugin should automatically detect both.

If not, Go to Settings -> Languages & Frameworks -> Zig, and point the Toolchain Location and ZLS path to the zig compiler's directory and the ZLS executable, respectively.

If everything is set up correctly, an LSP status indicator should appear in the bottom right corner and turn to green when you open a .zig file in the editor.

Helix

If zls and zig are in your PATH, everything should work out of the box.

To apply in-editor configuration or manually specify paths to zls or zig, open <config_dir>/helix/languages.toml and add the following:

[language-server.zls]
# omit the following line if `zls` is in your PATH
command = "/path/to/zls_executable"
# There are two ways to set config options:
#   - edit your `zls.json` that applies to any editor that uses ZLS
#   - set in-editor config options with the `config.<name>` fields below.
#
# Further information on how to configure ZLS:
# https://github.com/zigtools/zls/wiki/Configuration

# Whether to enable build-on-save diagnostics
# config.enable_build_on_save = true
# omit the following line if `zig` is in your PATH
config.zig_exe_path = "/path/to/zig_executable"

Further information on languages.toml files.

To make sure that Zig and ZLS are set up as expected you should run the Helix health check:

hx --health zig

For more information on the health check results refer to Health check.

Neovim / Vim8

The mason package manager can only install the latest tagged release of ZLS which should not be used with Zig master. Do not use ZLS from mason with Zig master.

nvim-lspconfig

The following two configs only contain the necessary ZLS specific configuration. Please refer to nvim-lspconfig on how to setup everything else like keybindings or autocompletion.

Install the vim-plug plugin manager.

init.lua with vim-plug
local vim = vim
local Plug = vim.fn['plug#']

vim.call('plug#begin')
  Plug('neovim/nvim-lspconfig') -- https://github.com/neovim/nvim-lspconfig
  Plug('ziglang/zig.vim')       -- https://github.com/ziglang/zig.vim
vim.call('plug#end')

-- don't show parse errors in a separate window
vim.g.zig_fmt_parse_errors = 0
-- disable format-on-save from `ziglang/zig.vim`
vim.g.zig_fmt_autosave = 0
-- enable  format-on-save from nvim-lspconfig + ZLS
--
-- ZLS uses `zig fmt` as the formatter.
-- The Zig FAQ answers some questions about `zig fmt`:
-- https://github.com/ziglang/zig/wiki/FAQ
vim.cmd [[autocmd BufWritePre *.zig lua vim.lsp.buf.format()]]

local lspconfig = require('lspconfig')
lspconfig.zls.setup {
  -- Server-specific settings. See `:help lspconfig-setup`

  -- omit the following line if `zls` is in your PATH
  cmd = { '/path/to/zls_executable' },
  -- There are two ways to set config options:
  --   - edit your `zls.json` that applies to any editor that uses ZLS
  --   - set in-editor config options with the `settings` field below.
  --
  -- Further information on how to configure ZLS:
  -- https://github.com/zigtools/zls/wiki/Configuration
  settings = {
    zls = {
      -- omit the following line if `zig` is in your PATH
      zig_exe_path = '/path/to/zig_executable',
    }
  }
}
init.vim with vim-plug
call plug#begin('~/.config/nvim/plugged')
  Plug 'neovim/nvim-lspconfig' " https://github.com/neovim/nvim-lspconfig
  Plug 'ziglang/zig.vim'       " https://github.com/ziglang/zig.vim
call plug#end()

-- disable format-on-save from `ziglang/zig.vim`
let g:zig_fmt_autosave = 0
-- don't show parse errors in a separate window
let g:zig_fmt_parse_errors = 0

:lua << EOF
  -- enable format-on-save from nvim-lspconfig + ZLS
  --
  -- ZLS uses `zig fmt` as the formatter.
  -- The Zig FAQ answers some questions about `zig fmt`:
  -- https://github.com/ziglang/zig/wiki/FAQ
  vim.cmd [[autocmd BufWritePre *.zig lua vim.lsp.buf.format()]]

  local lspconfig = require('lspconfig')
  lspconfig.zls.setup {
    -- Server-specific settings. See `:help lspconfig-setup`

    -- omit the following line if `zls` is in your PATH
    cmd = { '/path/to/zls_executable' },
    -- There are two ways to set config options:
    --   - edit your `zls.json` that applies to any editor that uses ZLS
    --   - set in-editor config options with the `settings` field below.
    --
    -- Further information on how to configure ZLS:
    -- https://github.com/zigtools/zls/wiki/Configuration
    settings = {
      zls = {
        -- omit the following line if `zig` is in your PATH
        zig_exe_path = '/path/to/zig_executable',
      }
    }
  }
EOF

CoC

Add ZLS in your coc-settings.json (open it using :CocConfig) like this:

{
  // Show inlay hints in the editor. Inlay hints are short annotations within the code,
  // which show variable types or parameter names.
  "inlayHint.enable": true,
  "semanticTokens.enable": true,

  "languageserver": {
    "zls": {
      "command": "zls",
      "filetypes": [ "zig", "zon" ]
    }
  }
}

YouCompleteMe

  • Install YouCompleteMe from here.
  • Add these lines to your vimrc:
"ensure zig is a recognized filetype
autocmd BufNewFile,BufRead *.zig set filetype=zig
let g:ycm_language_server =
    \\ [
    \\{
    \\     'name': 'zls',
    \\     'filetypes': [ 'zig' ],
    \\     'cmdline': [ '/path/to/zls_executable' ]
    \\    }
    \\ ]

Emacs

  • Use the inbuilt eglot mode. Make sure ZLS is in your path.
  • zig mode is also useful.

Use M-x eglot in a zig-mode buffer to start the server.

Doom Emacs

  • Enable :tools lsp module.
  • Enable :lang (zig +lsp) module.
  • Run doom sync in a terminal.

Spacemacs

  • Add lsp and zig to dotspacemacs-configuration-layers in your .spacemacs file.
  • If you don't have zls in your PATH, add the following to dotspacemacs/user-config in your .spacemacs file:
(setq lsp-zig-zls-executable "/path/to/zls_executable")

Kate

Kate has builtin support for Zig and automatically asks you to enable ZLS if if is found in your $PATH.

You can enable some LSP related settings like "Inlay Hints" or "Format on Save" under Settings -> LSP Client -> Client Settings

If you wish to manually specify the path to the ZLS executable, open Settings -> LSP Client -> User Server Settings and add the following snippet:

{
  "servers": {
    "zig": {
      "command": ["/path/to/zls_executable"],
      "url": "https://github.com/zigtools/zls",
      "highlightingModeRegex": "^Zig$"
    }
  }
}

Configuration

In-Editor Configuration (recommended)

In-Editor Config (or Workspace Config) will integrate with the config system of you editor to configure ZLS on a per-editor basis.

Some editors (like VS Code) also allow workspace-specific configuration. If you want to share the same configuration across multiple editors, please refer to the zls.json alternative.

This feature is available for the following editors:

zls.json

You can configure ZLS by creating a zls.json configuration file. This config will apply to all editors that use ZLS.

Here is an example of how a zls.json could look like:

{
  "zig_exe_path": "/path/to/zig_executable",
  "semantic_tokens": "partial",
  "enable_build_on_save": true
}

The file must be valid JSON which cannot contain comments or trailing commas.

Available Configuration Options

You can find all available config options by looking at src/Config.zig or the JSON Schema.

Where should the zls.json be created?

ZLS since 0.14.0-dev.50+3354fdcb

Running zls env will show you where ZLS will look for the zls.json file:

{
  "version": "0.14.0-dev.50+3354fdcb",
  "global_cache_dir": "/home/anon/.cache/zls",
  "global_config_dir": "/etc/xdg",
  "local_config_dir": "/home/anon/.config",
  "config_file": null,
  "log_file": "/home/anon/.cache/zls/zls.log"
}

ZLS will look for a zls.json in the local_config_dir directory and then fallback to global_config_dir.

After creating the configuration file at $local_config_dir/zls.json, zls env should output the following:

{
  "version": "0.14.0-dev.50+3354fdcb",
  "global_cache_dir": "/home/anon/.cache/zls",
  "global_config_dir": "/etc/xdg",
  "local_config_dir": "/home/anon/.config",
  "config_file": "/home/anon/.config/zls.json",
  "log_file": "/home/anon/.cache/zls/zls.log"
}
ZLS before 0.14.0-dev.50+3354fdcb

Running zls --show-config-path will show a path to an already existing zls.json or a path to the local configuration folder instead.

> zls --show-config-path
info  ( main ): No config file zls.json found.
info  ( main ): A path to the local configuration folder will be printed instead.
/home/anon/.config/zls.json

Per-build Configuration (advanced)

The following options can be set on a per-project basis by placing zls.build.json in the project root directory next to build.zig.

Option Type Default value What it Does
relative_builtin_path ?[]const u8 null If present, this path is used to resolve @import("builtin")
build_options ?[]BuildOption null If present, this contains a list of user options to pass to the build. This is useful when options are used to conditionally add packages in build.zig.

BuildOption

BuildOption is defined as follows:

const BuildOption = struct {
    name: []const u8,
    value: ?[]const u8 = null,
};

When value is present, the option will be passed the same as in zig build -Dname=value. When value is null, the option will be passed as a flag instead as in zig build -Dflag.