Raven
July 24, 2026 · View on GitHub
Raven is a static analyzer for R that resolves what's in scope at each line — catching undefined and used-before-defined variables even in a single script, and across files by following source() chains — without running your code. The same scope model drives the rest of its code intelligence — completions, go-to-definition, find-references, hover — so each reflects what's reachable at your cursor, not just what exists somewhere in the project. It also diagnoses syntax errors, and can optionally check code style and formatting.
Raven is fast and runs all of this in realtime in your editor, with diagnostics updating instantly as you type. It also fills a gap at the other end of the workflow: automated checks in pull requests — running raven check flags undefined variables and other errors before code merges, the kind of automated review that's table stakes for other languages but has long been missing for R analysis projects.
Doing this well in R is hard — part of why so little static tooling exists for the language. R leans heavily on non-standard evaluation (NSE): a function can take its arguments as unevaluated code and decide what the symbols mean at runtime, so col in dplyr::filter(df, col > 0) is a data-frame column, not an undefined variable. A checker that didn't account for this would flag idiomatic R as errors; Raven recognizes these NSE contexts and leaves them unflagged — though code that pulls names into scope at runtime, such as attach(), can still draw a false positive, which you resolve by declaring those symbols with a directive. The same analysis isn't only defensive: wherever it can determine an object's structure statically, Raven completes its fields — start typing fruit$a and it can suggest apple the moment you open the file, with no R session.
Beyond code intelligence, Raven's VS Code extension can bring the rest of an R workflow into the editor — an R console with plot and data viewers — but it's built to add to your setup rather than change it: those R-session features defer by default to REditorSupport or Positron, and the language server runs alongside or instead of r-language-server (details below).
Raven is fully open source (GPL-3.0) and editor-agnostic: it speaks the Language Server Protocol, so it runs in VS Code, Neovim, Zed, or any LSP client — including over VS Code Remote-SSH, so you can develop on a remote server with more compute than your laptop.
Status: Raven is under active development. It works well for day-to-day use but hasn't been widely announced yet. Bug reports and feedback are welcome!
Quick Start: Install from the VS Code Marketplace or OpenVSX, or download from the releases page. See Installation for details.
Raven's sibling project Sight implements a language server for Stata. Together they bring cross-file navigation, error detection, and code intelligence to two languages widely used in social science research.
Features
Code intelligence
- Completions — Symbols, packages, and function parameters — across files
- Go-to-definition — Jump to definitions across file boundaries
- Find references — Locate all usages of a symbol across your project
- Hover — Symbol info including source file and package origin
- Diagnostics — Undefined variable detection that understands sourced files and loaded packages
- Non-standard evaluation — NSE-aware diagnostics for data-masking, tidyselect, ggplot mappings, Shiny, foreach, and custom helpers
- Linting — Opt-in style/lint rules (line length, trailing whitespace, trailing blank lines, tabs, assignment operator, object names, infix spaces, commented code, indentation)
- Document outline — Hierarchical view with sections, classes, and nested functions
- Workspace symbols — Project-wide symbol search (Cmd/Ctrl+T)
- File path intellisense — Completions and cmd-click inside
source()paths - Smart indentation — Context-aware auto-indent with configurable argument and chain styles
- Cross-file awareness — Follows
source()chains and statictargets::tar_source()batches, and connects supported{tarchetypes}target factories and report documents - Module & import systems — Models static
{box}and{import}selective imports, binding only the names an import requests, with module privacy - Directives — Declare relationships and symbols the analyzer can't infer
- Syntax highlighting — R function names via LSP semantic tokens, plus JAGS and Stan syntax highlighting
Raven also provides lightweight support for JAGS (.jags, .bugs, .bug) and Stan (.stan) files: syntax highlighting, completions (keywords, distributions, versioned built-in callables, file-local symbols), JAGS hover, Stan hover, static signature help for JAGS built-ins, JAGS and Stan syntax diagnostics, conservative Stan undeclared-variable diagnostics, go-to-definition, find references, and document outline with model structure navigation. Native Stan/JAGS syntax findings share a configurable per-file limit (default 500; 0 for unlimited) in the editor and raven check; Stan semantic findings use a separate fixed 500-per-file bound. All three JAGS extensions are matched case-insensitively and receive strict JAGS-dialect validation; this does not claim general OpenBUGS, WinBUGS, MultiBUGS, or NIMBLE compatibility.
R session integration
- R console — Interactive R console with statement detection and a temp-file fallback for large blocks; supports R, arf, and radian
- Quarto & R Markdown — A consistent, theme-aware authoring and preview workflow for
.Rmd,.Rmarkdown, and.qmddocuments:- R code chunks — R language intelligence, execution commands, CodeLens buttons, navigation, and highlighting inside chunks
- R Markdown preview + export — Fast HTML preview with manual refresh, plus export to HTML, PDF, and Word
- Quarto preview + render — Preview and render
.qmddocuments with Quarto, including automatic refresh after saves
- Plot viewer — Plots render in a VS Code panel via httpgd, with history navigation, save (PNG/SVG/PDF), and theme-aware background
- Data viewer —
View(df)opens a virtualized grid backed by Apache Arrow; viewport-based rendering keeps scrolling responsive on multi-million-row frames - Help viewer — Scope-aware R help: hovering shows the function in scope at the cursor instead of falling through to a multi-package list when scope can't be inferred
How Raven Differs
Raven takes a static-analysis approach rather than attaching to a live R session, so it can start answering questions the moment a file is opened, without running user code. That has four practical consequences:
- Available immediately, even for code you haven't run — answers the moment you open a file, including code that errors halfway, is missing a dependency, or that you're only reading (onboarding to a repo, reviewing a pull request). A session-based tool can offer little until the code runs cleanly.
- Reflects what your code says, not what your session remembers — a tool tied to a live session sees whatever is in
globalenv()right now, possibly stale. Comment outlibrary(dplyr)while it's still attached in your session and a session-based tool keeps completingdplyrfunctions; Raven reads the file and knows it isn't loaded there. - Read-only and side-effect-free — computing scope never runs your code, so nothing it does (writing files, hitting a database, a long job) can be triggered. This is also what makes Raven safe to run behind an agentic/AI tool.
- Runs in CI and other headless environments — scope resolution needs no live R session, so Raven's diagnostics and lints run in CI (automated checks on pushes and pull requests) or any headless context. Use
raven checkfor the full diagnostic set (cross-file, undefined-variable, package) andraven lintfor style-only gating. See Automated checks in CI for a beginner-friendly guide and GitHub Actions / Bitbucket Pipelines examples.
See Why Raven exists for the origin and rationale.
Built to coexist, not replace. Raven layers onto your existing R setup two different ways, and neither one takes anything over.
The language server is additive. Its reason for being is static, cross-file analysis, and it runs happily next to r-language-server: install Raven and you get its diagnostics, completions, and navigation on top of whatever you already run. If you'd rather not have two providers offering completions, set r.lsp.enabled to false to turn REditorSupport's language server off and let Raven handle code intelligence alone. If you want to keep REditorSupport's language server but not its lintr style diagnostics, set r.lsp.diagnostics to false — you'll keep Raven's syntax and scope diagnostics without style linting. And if you want some of that style linting back, Raven ships its own opt-in lints (raven.linting.enabled), configurable through a .lintr file for backward compatibility, a raven.toml, or VS Code's settings UI — a point-and-click alternative to writing .lintr syntax by hand. Raven also folds in configurable syntax-aware indentation as you type; it never reformats whole files, so there's nothing for a dedicated formatter like Air (Posit) to collide with. The community has dedicated tools for these jobs — Air for formatting, lintr or Jarl for linting — and Raven is built to run alongside them.
The R console and viewers defer to whatever you already run. Raven's R console, its plot and data viewers, and its Knit Preview overlap with what REditorSupport, RStudio, and Positron already give you — and if you like their live-session, workspace-watcher style of working, Raven isn't trying to replace it. By default these features defer: under raven.rConsole.activation's auto setting they step aside whenever REditorSupport is enabled or you're running in Positron, so installing Raven never displaces the R integration you already have. They exist for two reasons. First, having built a language server that deliberately needs no live R session, I didn't want to then be forced to pair it with a tool that injects itself into one — so Raven gives you a complete R workflow you can run on its own. Second, I had particular preferences these viewers are built around: a data viewer that stays responsive on millions of rows, reopens after a VS Code restart, remembers sorts and filters across repeated View() calls, and shows value labels from imported Stata / SPSS data, all without waiting on a live R session (the frame streams out to Arrow on disk); help that lists only the function actually in scope (hover print() and you get base::print, not a list of every package that happens to define a print); and a fast .Rmd / .Rmarkdown preview that themes prose, syntax highlighting, and plots to match your editor. Turn them on everywhere with raven.rConsole.activation: "enabled". (Raven's scope-aware help viewer remains available regardless -- it only opens when you click the link in one of Raven's hovers, so it doesn't get in the way of anything else.)
For a detailed comparison with RStudio, Positron (Ark), and REditorSupport — covering both language intelligence and R session integration — see docs/comparison.md.
Installation
VS Code: Install from the VS Code Marketplace
Cursor, Positron, and other VS Code-based editors: Install from OpenVSX or download the .vsix file from the releases page and install manually.
Other editors: Download a pre-built binary from the releases page, then run raven --stdio and connect via your editor's LSP client. See Editor Integrations for Zed, Neovim, and AI agent configurations.
Automated checks / CI: Use raven check in GitHub Actions, Bitbucket Pipelines, or another CI system to catch analyzer diagnostics before code merges. See Automated checks in CI.
GitHub Actions: Use jbearak/setup-raven@v1 to install the pre-built CLI, then run raven check with the flags you want. See CLI.
Bitbucket Pipelines and Ubuntu CI: Install Raven from the signed apt repository in an Ubuntu image, then run raven check. See CLI.
Build from source: Install with cargo install --git https://github.com/jbearak/raven raven, or build from a local checkout. See Development Notes.
Documentation
Each feature above links to its own page. Beyond those:
- Editor Integrations — VS Code, Zed, Neovim, AI agents
- Configuration — All settings and options (alphabetical reference)
- Automated checks in CI — What CI is, why
raven checkbelongs there, and GitHub Actions / Bitbucket Pipelines templates - CLI —
raven check(full diagnostics) andraven lint(style) for CI and command-line usage - R Package Development — Package mode, visibility rules, and build commands
.RprofileStartup Prelude — How Raven models project startup files for script scope- Non-Standard Evaluation — How Raven handles NSE, when to add
# raven: nse, and when to use other escape hatches - Speeding Up Cross-File Analysis — When
# raven: self-containedimproves analysis of high-fan-out source graphs - Coexistence — Running alongside REditorSupport (vscode-R) and Positron
- Comparison — How Raven compares to other R tools
- Chunk Keybinding Comparison — Chunk shortcuts across Raven, Quarto, RStudio, and REditorSupport
- Limitations — Features not yet implemented
Development
See Development Notes for build/test, profiling, and internal architecture.
Provenance
Raven includes code derived from Ark (MIT License, Posit Software, PBC) — initial LSP wiring and tree-sitter scaffolding — and from Raven's sister project Sight (also GPL-3.0) — the cross-file awareness system (directives + position-aware scope model). The bundled R and R Markdown TextMate grammars come from vscode-R-syntax (MIT). Raven's native lint compatibility tests adapt behavioral cases from lintr's test suite (MIT). Stan syntax diagnostics use tree-sitter-stan (MIT), pinned to an audited revision. The generated Stan callable and distribution metadata comes through the stanc3 npm package 2.39.1, which bundles the Stan compiler 2.39.0 (BSD-3-Clause). Raven's JAGS parser and JAGS 4.3.2 catalog are clean-room interoperability artifacts built from independently authored syntax rules and factual metadata, with the official command-line oracle and source URL/SHA-256 retained for reproducibility; Raven does not copy or bundle JAGS code or documentation.
Raven's downloadable package-symbol database is built from CRAN/Bioconductor metadata published by r-universe, maintained by rOpenSci. See Package database.