Comparing Elixir language servers: ElixirLS, Lexical, and Next LS

I frequently switch between ElixirLS, Lexical, and Next LS in order to test each out and compare/contrast. I decided to create a brief feature comparison matrix with some of my findings: Elixir Language Server Comparisons · GitHub

I reached out to some authors and devs familiar with each tool in order to be as fair as possible. Each of these tools is a large undertaking and takes tons of time and effort from the maintainers. A simple 2D comparison table can’t tell the whole story, so take it with a grain of salt. I’ll be doing my best to maintain and update the list as tooling evolves and adds/changes functionality. :smile:


Thanks for putting that together!


That’s really cool. One thing I think none of the language servers support right now is working inside liveview sigils, things like go to definition, hover,…

That’s something that might be useful to track as well?


Oh yes, go to definition on HEEX components would be magical :star_struck:


I’ve asked over on discord in the editor-tooling channel just a few days ago.
As far as I understood it doesn’t look promising

Quoting icecreamcohen here

If we can get the ast for heex, we might be able to work some magic, but I agree with Scott, it’s not easy

It’s even trickier, we’d likely need to make a source map from the heex to the ast, since the language server reports your cursor in terms of the heex file

The fact that it’s a sigil only slightly complicates things

1 Like

Also referencing this issue on elixir-ls: Add support for function components · Issue #804 · elixir-lsp/elixir-ls · GitHub

The stance of elixir-ls is that this should be implemented separately, so I guess, it’s not something we’re going to see immediately.
To bad, go to reference on a function component would be so useful :slight_smile:

1 Like


Not sure where you’d like specific content discussion (here or in the GitHub comments section).

A couple notes:

  • Including which mainstream editors have packages for simple installation would be useful in the list. EDIT: sorry I was just blind… you’ve got it.

  • I have anecdotal experience that ElixirLS works with monorepos, depending on exactly what you mean by monorepo support. My current project is a monorepo style project with many Elixir projects inside the “project workspace” of my editors. I have have worked this in both VSCode and in my current editor, Sublime Text. Here’s a screenshot of a few sample directories in the larger project workspace; note the .elixir_ls built in the root of each Elixir project:

That works, but it starts up an Elixir LS instance for each project.

With “workspace folders” support (which is what is meant by “monorepo support”), the editor will boot up a single language server instance to handle all of the projects.


Hmmm… at some level, for a checklist like the OP published, this feels like an odd dividing line between “monorepo support: yes” vs. “monorepo support: no or unknown”. My sense is that it conflates a feature, can the tool be used with monorepos, with the implementation details of how the feature is implemented. As a simple user, what I first want to know is does the tool allow me to work across the multiple Elixir projects in my monorepo: in a simple checklist sense this to me sounds like a “yes” for ElixirLS (I’ve not tried the others). Now to be fair to your point, there may be reasons why the ElixirLS implementation of that kind of support is inferior that of NextLS. But depending on the nature of my project I may never reach a point where that distinction actually matters in practice.

Finally, if we are to take the disclaimers at the top of the list at face value:

  • This comparison does not take performance into account.
  • Language servers might support similar features that operate differently.

It seems as though the implementation difference you describe shouldn’t be a factor in deciding if a feature is supported or not. If there are actual feature differences, meaning I as a user gain or lose capabilities in working with the monorepo, the argument will be on firmer footing.

(update: just saw that you don’t use neovim, sorry)

If you’re using nvim-lspconfig, I’ve updated the default config used for elixir-ls. nvim-lspconfig will now give higher preference to detecting your .git folder in your monorepo.

This should mean no more .elixir-ls folder in every project, just the one for your monorepo (if it has a .git folder).

My sense is that it conflates a feature, can the tool be used with monorepos, with the implementation details of how the feature is implemented.

The monorepo support is whether the tool itself can understand a monorepo, vs if it can be naively used in a monorepo.

For example, Next LS supports Workspace Folders (monorepo), so if you do a Workspace Symbols query (Next LS | elixir-tools & Code Navigation in Visual Studio Code) it will search for symbols across your entire workspace (all workspace folders), rather than just the one you are in.

ElixirLS works with VSCode multi-root workspaces but the support for that is implemented in VSCode extension. It currently starts separate language server processes in each workspace directory. I’m not aware if multi-root workspaces are supported in other editor extensions wrapping ElixirLS


I think this is a better example of “feature” that I was trying to get at. I don’t really have much call for this sort of thing myself, but I could see other scenarios where it might be useful. I also see why the earlier distinction you were trying to make was being pointed out, and in the context of the above it makes more sense.

1 Like

Seems to be in Sublime Text. This is the functionality I most depend on in my project; as you point out, back when I was using VSCode I had it working there, too.

To be honest, the way the different Elixir projects are used in my code base, per workspace directory LSP processes don’t bother me and is consistent with what I need to manage the monorepo in the editor.

9 posts were split to a new topic: Split from language servers thread