Skip to content


You need first lsp-mode, that is a Emacs client for an LSP server. Then you need to install the specific LSP server for your language. Finally, call M-x lsp or use the corresponding major mode hook to autostart the server.


lsp-mode has multiple ways to install it.

Manually via MELPA#

The recommended way to install lsp-mode is via package.el - the built-in package manager in Emacs. lsp-mode is available on the two major package.el community maintained repos - MELPA Stable and MELPA.

M-x package-install RET lsp-mode RET

When updating your packages with package.el, we recommend the following procedure:

1. Delete your LSP-related packages
2. Restart Emacs
3. Install the new versions of the packages.

Doom Emacs#

Doom Emacs has a module to install and configure lsp-mode automatically, you just need to add lsp below :tools in your init.el.

To add lsp-mode support to some language, you can add the +lsp flag to the language you want. Example:


(clojure +lsp)
(dart +lsp)
(java +lsp)

For Doom Emacs module flags and more information, check the doom-emacs lsp module documentation.


lsp-mode is included in spacemacs develop branch. Add lsp to dotspacemacs-configuration-layers and configure the language that you want to use to be backed by lsp backend.

Vanilla Emacs#

You could go minimal and use lsp-mode as it is without external packages with the built-in flymake and completion-at-point or you could install the following extensions for better experience:

  • lsp-ui for fancy sideline, popup documentation, VScode-like peek UI, etc.
  • flycheck if you prefer the more popular flycheck over renewed flymake. lsp-mode will automatically pick it up.
  • company-mode for completion popups.
  • lsp-treemacs for various tree based UI controls (symbols, errors overview, call hierarchy, etc.)
  • helm-lsp provides on type completion alternative of xref-apropos using helm.
  • lsp-ivy provides on type completion alternative of xref-apropos using ivy.
  • dap-mode if your language is supported by the debugger.
;; if you want to change prefix for lsp-mode keybindings.
(setq lsp-keymap-prefix "s-l")

(require 'lsp-mode)
(add-hook 'XXX-mode-hook #'lsp)

Where XXX could be major mode like python, java, c++. Alternatively, if you want to minimize your configuration you may use prog-mode-hook. In case you do that, lsp will try to start for each programming mode and echo a message when there is no client registered for the current mode or if the corresponding server is not present. In addition, lsp-mode will automatically detect and configure lsp-ui and company-mode. To turn off that behavior you could set lsp-auto-configure to nil.

To defer LSP server startup (and DidOpen notifications) until the buffer is visible you can use lsp-deferred instead of lsp:

(add-hook 'XXX-mode-hook #'lsp-deferred)


Replace (require 'lsp-mode) with the following if you use use-package.

(use-package lsp-mode
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "C-c l")
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (XXX-mode . lsp)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp)

;; optionally
(use-package lsp-ui :commands lsp-ui-mode)
;; if you are helm user
(use-package helm-lsp :commands helm-lsp-workspace-symbol)
;; if you are ivy user
(use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
(use-package lsp-treemacs :commands lsp-treemacs-errors-list)

;; optionally if you want to use debugger
(use-package dap-mode)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language

;; optional if you want which-key integration
(use-package which-key

To defer LSP server startup (and DidOpen notifications) until the buffer is visible you can use lsp-deferred instead of lsp:

(use-package lsp-mode
    :hook (XXX-mode . lsp-deferred)
    :commands (lsp lsp-deferred))

When you are not using package.el to install lsp-mode make sure to put clients folder to the load-path:

;; The path to lsp-mode needs to be added to load-path as well as the
;; path to the `clients' subdirectory.
(add-to-list 'load-path (expand-file-name "lib/lsp-mode" user-emacs-directory))
(add-to-list 'load-path (expand-file-name "lib/lsp-mode/clients" user-emacs-directory))

Install a language server#

For instructions on how to install a server for your language, check the available supported servers.

Last update: June 10, 2024