There are a few LSP client implementations available for JetBrains IDEs.
Comparisons may be biased, but I try to make it accurate. Older client implementations like Ballerina’s lsp4intellij are not covered.
Why j-a.dev LSP Is A Good Choice
Of course, this is my own opinion.
tl;dr This LSP client is bundled with plugins, implements more LSP features and uses Kotlin, Coroutines and newer APIs for a better integration.
This LSP client is my second attempt to write an LSP client.
The first attempt was created from scratch for the first versions of Swift Support.
It used Java Future
a lot because the underlying LSP4J relies on it.
JetBrains is using Kotlin Coroutines more and more for concurrency and cancellable UI.
Using Future
in this setup and handling multiple, dependant Futures
is difficult and prone to errors.
With my second attempt, I’m using Kotlin and Kotlin Coroutines. In my opinion, this approach is working well to handle concurrency and cancellation.
Other clients like the older lsp4intellij and also RedHat’s LSP4IJ use the PSI
APIs for many features.
More recent major versions of the IDEs provide alternative APIs, which are more generic and allow for a better integration.
For example, this client uses newer APIs for “Go to Definition”, “Find Usages” and “Rename” for a more consistent integration into the IDE.
For my own products, I want an invisible implementation of LSP support and want to support all IDEs.
This is only possible with my LSP client.
For example, if I implement custom language support for Swift and use sourcekit-lsp as LSP server,
then I want to integrate this as good as possible.
I want to ship the LSP support with the plugin for a self-contained setup and quick installation.
Also, I don’t want to show unnecessary LSP UI to a user.
I want a plugin to provide its own settings and to programmatically manage the LSP server setup.
Comparison with JetBrains’ LSP Client
JetBrains maintains its own implementation of an LSP client.
The implementation is only available for their commercial products like IntelliJ Ultimate or WebStorm.
It’s not available for the free IDEs like IntelliJ Community or PyCharm Community.
Advantages of the JetBrains LSP client:
- JetBrains can provide the best integration of LSP features because it maintains the platform
- It’s easy to integrate and works well
- Plugins using it can provide a single build for several major versions
Disadvantages of the JetBrains LSP client:
- It’s only available for their commercial products
- It covers fewer features of the LSP specification
- New features are not backported.
For example, if support for an LSP feature is added in 2025.1 it won’t be backported to 2024.3 and earlier versions. If you rely on a particular feature, then you’re limited to the major version implementing it.
Comparison with RedHat’s LSP4IJ
RedHat is maintaining an LSP client implementation at github.com/redhat-developer/lsp4ij/.
RedHat’s client follows a different approach than j-a.dev LSP.
It attempts to be a generic, configurable solution to provide out-of-the-box support for a wide range of available LSP
servers.
To use it, a plugin has to declare a dependency on the LSP4IJ plugin. Both plugins have to be installed to make LSP support available.
Advantages of the RedHat LSP client:
- Most LSP features are covered
- Advanced support for TextMate-based language support
- It’s available for all IDEs, including Community editions
- It’s open-source and licensed under the EPL-2.0 license
Disadvantages of the RedHat LSP client:
- A third-party plugin is required to enable LSP support in your own plugin.
Bundling LSP support with a plugin and making it invisible to a user is not possible. - LSP4J’s UI is visible to a user and settings for generic LSP support are shown
- There’s optional telemetry, but it’s turned off by default
- It does not use Kotlin or Coroutines, which are JetBrains’s choice for concurrency