Blog Supporters Resume
Part time open-sourcerer, Linux enthusiast, Rust fanatic

Easier way to setup LSP on neovim

September 10, 2021 — (Last edited on November 09, 2021)


You probably might already be used to the standard way to setup LSP on neovim with lspconfig, but on the long run, depending on the number of different languages you’re working with, you might stumble upon the following problem (quoted from this article)

For example, you install pyright with npm, gopls with go get, cmake-language-server with pip, rust_analyzer by downloading a release from GitHub, and yaml-language-server can only be installed with yarn but not with npm. And it gets worse! To get an up to date version of the HTML/CSS/JSON language servers you need to download the latest VSCode release and extract the language servers from there. Similarly, to get the tailwindcss-intellisense language server, you’ve got to extract it from the VSCode extension.

You get the point, having such a spaghetti of package managers that you probably won’t use more than once is not desirable (and we’re not even including the part of migrating all this mess to a new system) is not desirable


The answer for such problem is nvim-lsp-installer, in short, it provides a nice :LspInstall <language> for leveraging all the setup required for getting a LSP working


You can install it with your neovim plugin manager of choice, i’ll be using paq-nvim as an example:

require 'paq-nvim' {
    -- considering that you already have it at this point


First, the basics, import nvim-lsp-installer, enable snippet support with a completion engine of your choice (i’ll be using nvim-cmp), and create a table containing language servers names as keys, and their respective configuration (if needed) as values

local lsp_installer = require 'nvim-lsp-installer'

-- enabling snippetSupport is required in order to make LSP work
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
capabilities = require 'cmp_nvim_lsp'.update_capabilities(capabilities)

local language_servers = {
    ['css'] = {},
    ['html'] = {},
    ['json'] = {},
    ['typescript'] = {}

Now, we must loop the language_servers table in order to properly install each one of the specified language servers, and set them up with their respective configurations

-- installs language servers
local installed_servers = require 'nvim-lsp-installer.servers'
for server_name in pairs(language_servers) do
    local ok, server = installed_servers.get_server(server_name)
    if ok and not server:is_installed() then

Having done that, now the last step is starting up installed server, this can be done with the on_server_ready listener:

    local opts = language_servers[server.name]

Shoutout to Karim Abou Zeid for creating such an amazing plugin!