DEV Community

Cover image for Language Server Protocol Introduction
Oleg Potapov
Oleg Potapov

Posted on

Language Server Protocol Introduction

Language Servers is not a concept commonly used by the majority of software developers in their work. However, a lot of us use it every day unknowingly, because usually it’s a hidden part in the developer’s toolkit.

Although not all the IDEs and code editors support Language Server Protocol, chances are you are already using one or several of such servers.

But even more indispensable this protocol might be not for the “users” of this tooling, but for its “providers” - authors of programming languages and development frameworks, who have to provide some developer tools as an additional benefit of their library.

The Problem

There are plenty of modern IDE and code editors: VS Code, Visual Studio, PyCharm, IntelliJ IDEA. Even Vim and Emacs are still alive and have modern modifications. A new generation of AI-based tools is also here (Cursor). And the number of modern programming languages is even larger than the number of editors (I won’t number them all). Using any programming language, a developer expects to have this language supported by the code editor of his choice. By “support” we mean such options as syntax highlighting, autocomplete, automated refactoring and other handy tools we've got so used to.

At first, IDE creators tried to have built-in support for the majority of the existing languages in their core product. But soon it became clear how hard it is to support everything in one programming product. Thus, there are only two ways for IDE to stay competitive - either focus on a small range of supported languages and be really good at it(for example, JetBrains with their PyCharm and RubyMine), or create a flexible plugin ecosystem, which allows third party developers to extend the existing functionality of the editor.

Having a plugin system is great, especially if you use a popular language. There definitely will be an enthusiast (likely a bunch of them) who will implement all the necessary features in the extensions for your editor. But things get worse when you are a creator of a programming language or framework, which has not gone mainstream (yet?). Without a correct IDE support, no one will go for it, so you will have to provide all the necessary developer tools with your language. Sounds good, but to do that you should know Python to create a Sublime plugin, TypeScript to do that for VS Code and even … VimL for Vim! And, of course, you need a lot of time for implementation.

The Protocol

Yeah, we all know this meme, but I couldn’t resist inserting it here. So, I think you can imagine what happened next.

Microsoft decided to solve these issues by entering the new standard called LSP (Language Server Protocol) [1]. The goal was to unify the development of the reach code editor actions across different IDEs, since most of these actions are basically the same. The idea is to allow developers to provide programming language support without relying on any particular IDE [2].

The fact that Microsoft owns Visual Studio Code - one the most popular code editors nowadays, helped the standard to become more and more popular and now it is supported by a wide range of other editors and programming languages.

How does it work

As the name states, communication through the Language Server Protocol requires a client and a server part. Client part is the same for all the languages and is usually developed for every editor by its team, while the server part is usually maintained by the language authors or community members.

From the image above you can see the main components of this concept:

  • Editor - the main process of the editor or IDE, that handles user interactions with code files
  • Extension - detects proper events or file changes and sends requests to the Language Server, using Language Server Protocol
  • Language Server - the server process implemented in any programming language responsible for receiving requests from editor extension and generating responses in the defined format

A small example. Let’s say an editor user wants to click on some language object (class, function or something else) and jumps to its definition. What happens in this case? First, the user calls the “Go-to-definition” feature using one of the methods provided by the editor. It might be Ctrl-click or any other key combination (Language Server doesn’t care about it, because it is the responsibility of the editor). An extension reacts to this event and sends a corresponding request to the Language Server with the type textDocument/definition. This request contains a file URI and a position inside the document where the event happened. Having this information the Language Server finds the location of the proper object definition and responds with its file name and position inside the file. The editor receives the response and opens the file. Of course, this is a simplified description of the request, there is full specification of the definition request and response in the documentation[4].

One thing should be additionally mentioned here. In the process of code editing the editor and the server send a lot of requests to each other - one for every text change, click or hover. And this communication should be so fast that the user shouldn’t notice any delay between his action and the editor's reaction. That’s why TCP wouldn’t be the best choice for such communication, even though it happens on a single machine. Instead it uses RPC protocol, or, to be more exact, one of its modifications called JSON-RPC. [5]

Benefits and drawbacks

Language Server Protocol mostly makes the life easier for languages (or programming frameworks) maintainers. The main benefits of LSP are:

  • no need to create a separate plugin for every editor
  • same amount of features with the same logic in any editor
  • you can use any technology to build the language server, including the language you build it for, for example Elixir language server elixir-ls is completely written in Elixir [3]

However, with all these benefits come several drawbacks:

  • the end-user should install and run one additional process
  • language server is more limited than editor-specific plugin
  • separate process is slower than built-in tools (often it's not a problem, though)
  • an additional process is an additional point of failure - it can crash, consume too much memory, etc.
  • not all the editors have LSP support and some of the LS implementations have a lot of complaints

Conclusion

I hope this article helped you understand a simple but very useful concept of language servers. It’s getting more and more popular among developer tools creators and there is a chance that your favorite language already has its own language server implementation [6]. If not, maybe this article will encourage you to create your own LS for your language or framework.

Links

  1. Microsoft LSP
  2. Language Server Protocol
  3. elixir-ls
  4. textDocument/definition
  5. JSON-RPC
  6. A list of LSP implementations

Top comments (0)