chpl-language-server (CLS for short) is a language intelligence tool for the Chapel programming language. CLS provides many of the common features users expect from a modern development environment. It is built on top of the Language Server Protocol (LSP) and is designed to be editor-agnostic.

Getting Started

The easiest way to make CLS available is by using the chpl-language-server Makefile target. This will build the Dyno compiler frontend and the Python bindings for Dyno if needed, and place chpl-language-server into $CHPL_HOME/bin. Make sure that you satisfy the requirements for building the Python bindings.

make chpl-language-server
chpl-language-server --help

CLS can be used with any editor that supports the LSP. Listed below are setup instructions for some popular editors. If your preferred editor is not listed, consider opening an issue or pull request to add it.


The built-in LSP API can be used to configure CLS as follows:

local lspconfig = require 'lspconfig'
local configs = require 'lspconfig.configs'
local util = require 'lspconfig.util'

configs.cls = {
  default_config = {
    cmd = {"chpl-language-server"},
    filetypes = {'chpl'},
    autostart = true,
    single_file_support = true,
    root_dir = util.find_git_ancestor,
    settings = {},

vim.cmd("autocmd BufRead,BufNewFile *.chpl set filetype=chpl")


Install the chapel extension from the Visual Studio Code marketplace.


The extension is not yet available at the time of writing and the above link may not work until then. This section will be updated when it is available.

Supported Features

CLS supports a number of core features, with further features controlled by configuration options.


Not all editor integrations may support all features. This list details features that are supported by CLS itself, not by any particular editor.

Core Features

  • Diagnostics

    Errors and warnings are reported on file save. CLS also has limited support to fix some errors and warnings automatically with quick fixes.

  • Symbol Information

    CLS provides basic information about symbols in code, enabling various actions. For example, you can jump to the definition of a symbol, find all references to a symbol, and rename a symbol. Hovering over a symbol will show its definition and documentation. Selecting a symbol will highlight all references to it in the file.

  • Code Completion

    CLS provides limited code completion for symbols imported from modules or present in your code.

Optional Features

  • End of Block Markers

    CLS can display markers after a closing brace to indicate what block it closes. This feature is off-by-default, but can be enabled with --end-markers <marker_list>.

    <marker_list> is a comma-separated list of markers to display. The following markers are supported:

    • none: Do not display any end markers. This is the default.

    • all: Display all end markers.

    • decl: Display markers for the end of a declaration (e.g. modules, records, functions, etc.)

    • loop: Display markers for the end of a loop (e.g. for, forall, while, etc.)

    • block: Display markers for the end of other important blocks (e.g. on, begin, etc.)

    End of block markers have a threshold of 10 lines of code. If a block is smaller than this, no end marker will be displayed. This threshold can be adjusted with --end-marker-threshold <threshold>.

Experimental Resolver Features

All of the following features are disabled without the --resolver flag. To use them, enable --resolver.


These features rely on the Dyno resolver, which is not finished and actively under development. It is fairly common for --resolver to cause CLS to crash or hang.

  • Type Information

    CLS can resolve the type of a symbol and allow jumping to type definitions.

  • Call Hierarchy

    Some editors support showing a call hierarchy for a symbol, both inbound calls and outbound calls. CLS supports this basic feature, as well as enabling some additional features for this with generic functions.

The following features are extra visual aids:




Type Inlays

Type information can be displayed inline as an inlay hint.

--type-inlays (default), --no-type-inlays

Param Inlays

param values can be computed and displayed inline as inlay hints.

--param-inlays (default), --no-param-inlays

Evaluated Tooltips

param values can also be computed and displayed as tooltips.

--evaluate-expressions (default), --no-evaluate-expressions

Call Inlays

Names of literal arguments can be displayed inline as inlay hints.

--literal-arg-inlays (default), --no-literal-arg-inlays

Dead Code

Dyno can determine compile-time dead code, which CLS highlights in the editor.

--dead-code (default), --no-dead-code

Generic Instantiations

CLS can show the various instantiations of a generic function.

No flag, on by default

Configuring Chapel Projects

Many Chapel projects are organized in a way that is not immediately understandable by CLS. For example, a project may have multiple source directories with any variety of build systems (make, mason, etc.). CLS can be configured to understand the structure of a Chapel project by creating a .cls-commands.json file in the root of the project. This is done automatically when chpl-shim is used to build a project.


The .cls-commands.json file is not intended to be edited by hand. It is generated by chpl-shim and should be treated as a build artifact. It is specific to the machine and build environment that generated it.

For example, the following can be used to configure CLS to understand a project using make:

$CHPL_HOME/tools/chpl-language-server/chpl-shim make

This is similarly done for mason projects:

$CHPL_HOME/tools/chpl-language-server/chpl-shim mason build


The above commands assume a from-source build of Chapel. An installed Chapel may require a different path to chpl-shim.


First-class mason support is currently planned (but not yet implemented), avoiding the need for chpl-shim in mason projects.