# REditorSupport languageserver: an LSP server for R and the clients that can drive it

> The languageserver package implements the Language Server Protocol for R, giving editors hover, completion, diagnostics and formatting over a running R session. It is usable from VS Code, Emacs, Vim, JupyterLab and several other clients, but installing it means compiling native dependencies first.

**REditorSupport/languageserver** — An implementation of the Language Server Protocol for R

- Repository: https://github.com/REditorSupport/languageserver
- Stars: 679 · Forks: 119
- Language: R
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/reditorsupport-languageserver

## A protocol server for R, not a new R IDE

languageserver is an implementation of the Language Server Protocol for the R language. It does not try to be an IDE, a package manager or a replacement for your R session. Instead it exposes R knowledge over a protocol that editors already speak, so the editor keeps its own look and the R-specific behaviour arrives as features: hover text, completion, signature help, go to definition, references, document symbols, code actions, code lenses and formatting. The package also handles document synchronisation and publishes diagnostics, which is what lets an editor underline a problem in an R file without you running a linter yourself. The audience is therefore people who already write R somewhere else, whether that is a terminal, a notebook or a full IDE, and who want their editor to understand the language while they type. Nothing in the documentation suggests you can point it at any language other than R, so treat it as an R-only component in your editor setup.

## Workspace indexing runs in the background and reports progress

The first thing you notice after connecting a client is delay, and the reason is that the server discovers and parses your R files before it can answer questions about them. Workspace discovery and indexing run in the background rather than blocking the editor. Clients that advertise LSP work-done progress support can display an Indexing R workspace indicator while R files are discovered, indexed and parsed, and once discovery completes the reports include file counts and a percentage. The client decides where that information appears, whether in a status bar, a progress panel or somewhere else. That design has a practical consequence for evaluation. A large project will feel slow the first time you open it, and the slowness is the price of the server having a picture of the whole workspace rather than just the file in front of you. Clients without work-done progress support still get the features, they just get them without a visible indication of what is happening, which is worth keeping in mind when diagnosing an apparently unresponsive server.

## Client support is broad, and the setup differs for every editor

The list of supported editors is long, and the configuration for each is genuinely different, so this is the part of the setup that deserves attention. VS Code uses the vscode-R extension, Atom the atom-ide-r extension, and Sublime Text the R-IDE extension. NeoVim can use its own LSP client, or you can go through coc.nvim and install the coc-r-lsp plugin. Emacs has two routes: the native eglot-mode client, or lsp-mode. JupyterLab works through jupyterlab-lsp. BBEdit has support preconfigured from version 14.0 onwards. Nova uses the R-Nova extension. That mix matters because the server alone does nothing for you: you still need the client side, and the client is where the differences live.

## The services checklist covers the everyday editing requests

The documentation keeps an explicit checklist of implemented protocol services, and it is worth reading as a scope statement rather than a feature list. Text document synchronisation and publishDiagnostics are there, which is the pair you need for live error reporting. On the interactive side there is hoverProvider, completionProvider and completionItemResolve, signatureHelpProvider, definitionProvider and referencesProvider for navigation, documentHighlightProvider for the current symbol, documentSymbolProvider and workspaceSymbolProvider for outline and symbol search, codeActionProvider and codeLensProvider for inline edits and hints, and documentFormattingProvider with documentRangeFormattingProvider for reformatting. The README also lists documentation sections for settings, for linters, for customizing server capabilities and for customizing formatting style, so the server can be tuned rather than accepted as is. The README states the project is still under active development, and the release history backs that up, with v0.3.19 on 2026-09-13 and v0.3.18 on 2026-09-11 following v0.3.17 on 2026-03-07. The last push was on 2026-10-18.

## Installing the R package from CRAN, r-universe or GitHub

The package is published on CRAN, and that is the shortest route into a working setup:

```r
install.packages("languageserver")
```

For the newest features the project points at its own r-universe repository, which serves a daily development build. The repos argument keeps your normal mirror in the list so other packages still resolve:

```r
install.packages("languageserver", repos = c(
    reditorsupport = "https://reditorsupport.r-universe.dev",
    getOption("repos")
))
```

The third option installs the development version straight from GitHub, which needs the remotes package:

```r
# install.packages("remotes")
remotes::install_github("REditorSupport/languageserver")
```

After that, the server is a function call in R. The coc.nvim configuration shows the shape of it, launching R with the server entry point and restricting it to R filetypes:

```json
"languageserver": {
    "R": {
        "command": "/usr/bin/R",
        "args" : [ "--no-echo", "-e", "languageserver::run()"],
        "filetypes" : ["r"]
    }
}
```

The path to the R binary and the file type list are the two settings you are most likely to have to change on your own machine.

## Linux users compile native dependencies before anything else

Before the R package can be installed, system libraries have to be in place, and the documentation lists them per distribution family. On Debian and Ubuntu the list is build-essential, libcurl4-openssl-dev, libssl-dev, libxml2-dev, libuv1-dev and r-base:

```bash
# On Debian, Ubuntu, etc.
apt install --assume-yes --no-install-recommends build-essential libcurl4-openssl-dev libssl-dev libxml2-dev libuv1-dev r-base
```

Fedora and CentOS have their own equivalent set, and Alpine has a third:

```bash
# On Fedora, Centos, etc.
dnf install --assumeyes --setopt=install_weak_deps=False @development-tools libcurl-devel libxml2-devel openssl-devel libuv-devel R
```

```bash
# On Alpine
apk add --no-cache curl-dev g++ gcc libxml2-dev linux-headers make R R-dev
```

This is the step most likely to fail on a fresh CI image or a locked down workstation, and the failure shows up as a build error in the package installation rather than as anything to do with editors. macOS and Windows are not covered by these instructions in the documentation excerpt, so if you are on one of those systems you will need to look elsewhere for the dependency list. Either way, the server runs as an R process, so R itself has to be present and reachable by the client.

## Two ways to talk to R: protocol requests or a live session

The alternative to running an LSP server is the older route, where an editor plugin talks to a running R process directly and evaluates code as you work. The documentation names that pattern in the Emacs setup, where ess-mode is installed and hooked into ess-r-mode-hook, and the check for whether it works is to open an R file, place the cursor on a line and run M-x ess-eval-line. The difference in approach is precise. The ess-style route evaluates code in your session, which gives you results, plots and a console, while the LSP route answers editor questions such as what arguments a function takes or where a symbol is defined, and leaves execution to you. The two are complementary rather than competing, and nothing in the documentation requires you to give up the first to use the second. The protocol route also brings capabilities the session route does not provide, in the form of document formatting, code lenses and workspace symbol search, and it does so without the editor needing to understand R internals.

## Licence, packaging and what the repository layout implies

The project is not archived, and its licence is listed as a custom one that GitHub cannot classify, with the terms living in the LICENSE file in the repository. That is worth reading before you redistribute it in an internal image, since a licence that no automated tool can identify gives you no shortcut on compliance. The package layout is a conventional R package: DESCRIPTION and NAMESPACE at the top, R/ for the R sources, src/ for compiled native code, tests/ for the test suite, man/ and man-roxygen/ for documentation, and inst/ for shipped assets. Build and tooling files sit alongside it, including .Rbuildignore, .lintr, .travis.yml, codecov.yml and a .devcontainer/ directory for containerised development. The presence of src/ is the visible reason the system dependency install above matters, and the presence of codecov.yml and .travis.yml tells you the project tracks test coverage as part of its workflow rather than leaving it informal. The default branch is master, and the most recent release in the list is v0.3.19 from 2026-09-13.

## Conclusion

Adopt languageserver if your team edits R in a modern editor and wants completion, hover and diagnostics without leaving the file, and pick a client extension that already matches your editor. Do not expect it to replace an R session for evaluation, since it answers editor requests rather than running your code. Before wiring it into an editor, confirm the native build dependencies are present on your Linux machines, because a missing libuv or libxml2 stops the install before the server ever starts.

## FAQ

### How do I install the languageserver package for R?

Install it from CRAN with install.packages("languageserver"). You can also use the r-universe repository for a daily development build, or remotes::install_github("REditorSupport/languageserver") for the GitHub version.

### Which editors can use the R languageserver?

The documentation lists VS Code through vscode-R, Atom through atom-ide-r, Sublime Text through R-IDE, NeoVim through its own LSP client or coc.nvim with coc-r-lsp, Emacs through eglot-mode or lsp-mode, JupyterLab through jupyterlab-lsp, BBEdit from version 14.0 onwards, and Nova through R-Nova.

### Do I need system libraries to install languageserver?

Yes. The documentation lists build tools and libraries such as libcurl, libssl, libxml2 and libuv as prerequisites, with different package commands for Debian and Ubuntu, Fedora and CentOS, and Alpine.

### Why does the R language server feel slow the first time I open a project?

Workspace discovery and indexing run in the background, and R files are discovered, indexed and parsed before answers are available. Clients that advertise LSP work-done progress support can show an Indexing R workspace indicator with file counts and a percentage once discovery completes.

## Sources

- [Issues](https://github.com/REditorSupport/languageserver/issues)
- [README](https://github.com/REditorSupport/languageserver/blob/master/README.md)
- [REditorSupport/languageserver on GitHub](https://github.com/REditorSupport/languageserver)
- [Releases](https://github.com/REditorSupport/languageserver/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/reditorsupport-languageserver
