Configuration
Purpose and Scope
This page explains how rust-analyzer configuration is presented to users and tool integrators in the Rust repository. rust-analyzer is the first-party Rust language server, so configuration is not a single command-line file format owned only by rust-analyzer. Instead, the documented model starts from the Language Server Protocol, usually shortened to LSP, where an editor launches the server and sends configuration data as structured JSON. This matters because the same setting can appear in different user interfaces depending on whether the reader uses VS Code, Vim with COC, another LSP client, or a custom integration.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
The configuration chapter is intentionally split into a small explanatory page and a generated reference. The explanatory page defines the transport, shows how dotted rust-analyzer setting names become nested JSON objects, and gives a practical logging technique for checking what the server received. The generated page then lists individual configuration keys, defaults, anchors, and descriptions. When reading this documentation, treat the first file as the conceptual entry point and the generated file as the option catalog that editors and integrators should keep in sync with the implementation.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md, src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Relevant Source Files
src/tools/rust-analyzer/docs/book/src/configuration.md— Defines the user-facing configuration model, explains LSPinitializationOptions, shows the nested JSON shape, documentsRA_LOGverification, and introduces experimentalrust-analyzer.tomlsupport.src/tools/rust-analyzer/docs/book/src/configuration_generated.md— Provides the generated configuration option reference, including setting names such asrust-analyzer.cargo.buildScripts.enable, their defaults, anchors, and short behavioral descriptions.
Configuration Model
The central rule is that rust-analyzer receives configuration through LSP messages, not through one universal editor-specific file. The documentation says editors decide the exact format and location of configuration files. Some clients expose rust-analyzer-specific configuration UIs, while others require the user to understand how LSP initialization data is assembled. This is why a VS Code setting, a COC setting, and a hand-written LSP client configuration may look different on disk while still producing the same JSON object sent to rust-analyzer at startup.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
For editors that require lower-level configuration, the initial settings are sent in the initializationOptions field of the LSP InitializeParams message. The LSP specification leaves that field broadly typed, but rust-analyzer expects a JSON object. The documentation describes a path transformation: remove the rust-analyzer. prefix from the setting name, treat the remaining dotted name as a path, and put the setting value at that nested property. For example, rust-analyzer.procMacro.enable becomes a procMacro object containing an enable property.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
That path transformation is the most important concept for custom clients. It prevents a long flat list of editor keys from leaking into the wire format and gives rust-analyzer a structured configuration tree. A setting under cargo.buildScripts belongs to the Cargo/build-script part of the server configuration, while a setting under assist.termSearch belongs to code-action behavior. The generated reference keeps the public setting names stable for users, while the LSP JSON shape lets clients send a compact object that mirrors those names hierarchically.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md, src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Core Configuration Areas
The generated reference shows several option families. Assist settings control code actions and code generation choices. Examples in the supplied catalog include rust-analyzer.assist.emitMustUse, which can insert #[must_use] when generating as_ methods for enum variants, rust-analyzer.assist.expressionFillDefault, which chooses the placeholder expression for missing expressions in assists, and rust-analyzer.assist.preferSelf, which prefers Self over a concrete type name when inserting a type. These settings are editor-facing productivity choices: they do not change Rust semantics, but they change what code rust-analyzer proposes or writes.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Term search assists have their own tuning options. rust-analyzer.assist.termSearch.borrowcheck defaults to enabled, meaning generated suggestions are constrained by borrow checking. The generated description also notes the tradeoff: disabling it can produce more suggestions, but some may not borrow-check. rust-analyzer.assist.termSearch.fuel sets a unit-of-work budget, defaulting to 1800, for the term search used by assists. These two options illustrate a common rust-analyzer configuration pattern: the server exposes knobs for balancing suggestion breadth, correctness filtering, and CPU work during interactive editing.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Cache priming is another visible category. rust-analyzer.cachePriming.enable defaults to true and warms caches on project load. rust-analyzer.cachePriming.numThreads controls how many worker threads handle priming, with the documented default shown as "physical" and an automatic behavior described in the option text. These options are startup and responsiveness controls. A large workspace may benefit from warm caches once analysis starts, while constrained environments may need to reduce background work to keep an editor session responsive.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Cargo integration is one of the largest documented areas because rust-analyzer needs project structure, feature selection, target information, build-script output, and procedural macro artifacts to provide accurate analysis. The generated options include rust-analyzer.cargo.allTargets, which passes --all-targets to Cargo, and rust-analyzer.cargo.autoreload, which refreshes project information through cargo metadata when Cargo.toml or .cargo/config.toml changes. These settings connect editor analysis to the same package metadata that normal Rust builds use, rather than treating the source tree as unrelated loose files.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Build-script configuration is especially important because build scripts and procedural macros can affect code that the editor sees. rust-analyzer.cargo.buildScripts.enable defaults to true so rust-analyzer can run build.rs for more precise analysis. rust-analyzer.cargo.buildScripts.rebuildOnSave reruns proc-macro building and build-script execution when related sources change and are saved. rust-analyzer.cargo.buildScripts.useRustcWrapper uses RUSTC_WRAPPER=rust-analyzer while running build scripts to avoid checking unnecessary things. These defaults favor accurate, live analysis while trying to avoid excess work.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
LSP JSON Example
The documentation’s common example enables build-script support and procedural macro support by sending nested JSON. The key point is not just the two booleans; it is the shape. The editor or client sends a cargo object with a buildScripts object and a procMacro object with its own enable property. This is the wire-format equivalent of configuring settings such as rust-analyzer.cargo.buildScripts.enable and rust-analyzer.procMacro.enable in an editor UI.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
{
"cargo": {
"buildScripts": {
"enable": true
}
},
"procMacro": {
"enable": true
}
}When adapting this example, keep the generated setting name and the nested LSP structure mentally connected. A flat editor setting named rust-analyzer.cargo.extraArgs corresponds to a JSON property named extraArgs inside cargo. A flat editor setting named rust-analyzer.cargo.cfgs corresponds to a cfgs array inside cargo. The generated catalog shows defaults such as an empty array for extraArgs, and a default cfgs list containing debug_assertions and miri, plus syntax for enabling names, assigning values with key=value, or disabling entries with a leading !.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Build Script Override Reference
The generated option rust-analyzer.cargo.buildScripts.overrideCommand is a good example of an advanced setting with operational constraints. Its default is null, meaning rust-analyzer constructs its normal Cargo command. If supplied, the override must be an array of command-line arguments where the first entry is the command name. The command is required to output JSON, so it should include --message-format=json or a similar option. This is not a generic shell string; it is a structured command vector that rust-analyzer can execute predictably.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
The documented default command line for build scripts and procedural macros is based on Cargo check: cargo check --quiet --workspace --message-format=json --all-targets --keep-going. That command reflects rust-analyzer’s need for machine-readable compiler messages and workspace-wide information, not only successful binary output. In multi-workspace scenarios, the command is invoked for each linked project or workspace with the workspace root as the working directory, unless rust-analyzer.cargo.buildScripts.invocationStrategy changes that behavior. The visible strategies are per_workspace and once.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
{
"cargo": {
"buildScripts": {
"overrideCommand": [
"cargo",
"check",
"--quiet",
"--workspace",
"--message-format=json",
"--all-targets",
"--keep-going"
],
"invocationStrategy": "per_workspace"
}
}
}Use an override only when the default Cargo invocation does not match the project’s build environment. Common reasons include wrapper tools, generated code steps, or workspace launch constraints imposed by an editor integration. Because the command supplies build-script and procedural-macro data to the language server, an invalid override can make analysis less precise or fail to load generated artifacts. If a project needs this level of customization, document the command in the editor configuration alongside the reason for overriding the default.
Sources: src/tools/rust-analyzer/docs/book/src/configuration_generated.md
Verification and File-Based Configuration
The configuration chapter gives a concrete verification technique: set the RA_LOG environment variable to rust_analyzer=info and inspect config-related log messages. The expected logs should show both the JSON that rust-analyzer sees and the updated configuration. This is the best first troubleshooting step when an editor UI appears correct but the server behaves as if a setting is missing. It distinguishes editor-side storage problems from server-side interpretation problems by showing the actual configuration payload received by rust-analyzer.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
The same chapter also documents work-in-progress support for a rust-analyzer.toml file. That file can be located in the project root or in a user configuration directory such as ~/.config/rust-analyzer/. The documentation explicitly cautions that many configuration options are not supported there yet. In practice, this means editor and LSP configuration remains the primary, fully documented path, while TOML configuration is useful only when the desired options are known to work in that mode.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md
Compact Option Reference
| Setting | Default in generated docs | What it controls |
|---|---|---|
rust-analyzer.assist.emitMustUse | false | Adds #[must_use] when generating as_ methods for enum variants. |
rust-analyzer.assist.expressionFillDefault | "todo" | Placeholder expression for missing expressions in assists. |
rust-analyzer.assist.preferSelf | false | Prefers Self over a concrete type name when inserting a type. |
rust-analyzer.assist.termSearch.borrowcheck | true | Enables borrow-check filtering for term search assists. |
rust-analyzer.assist.termSearch.fuel | 1800 | Sets the work budget for term search assists. |
rust-analyzer.cachePriming.enable | true | Warms analysis caches on project load. |
rust-analyzer.cachePriming.numThreads | "physical" | Chooses worker threads for cache priming. |
rust-analyzer.cargo.allTargets | true | Passes --all-targets to Cargo. |
rust-analyzer.cargo.autoreload | true | Refreshes project info on Cargo configuration changes. |
rust-analyzer.cargo.buildScripts.enable | true | Runs build.rs for more precise analysis. |
rust-analyzer.cargo.buildScripts.overrideCommand | null | Replaces the Cargo command used for build scripts and procedural macros. |
rust-analyzer.cargo.cfgs | debug_assertions, miri | Supplies cfg options to rust-analyzer. |
rust-analyzer.cargo.extraArgs | [] | Adds extra arguments to every Cargo invocation. |
System-to-Code Mapping
At the documentation layer, configuration.md is the stable explanatory entry point for humans. It tells a reader where configuration travels, why editor-specific instructions differ, and how to inspect the effective configuration. At the generated-reference layer, configuration_generated.md is the enumerated contract for option names and defaults. The two files work together: one prevents users from misunderstanding the transport, and the other prevents clients from guessing setting names or default values.
Sources: src/tools/rust-analyzer/docs/book/src/configuration.md, src/tools/rust-analyzer/docs/book/src/configuration_generated.md
For next steps, first configure rust-analyzer through the editor integration whenever the editor provides first-class support. If you are writing or debugging an LSP integration, construct initializationOptions using the nested JSON rule and verify the payload with RA_LOG=rust_analyzer=info. If build scripts, procedural macros, or workspace metadata look wrong, inspect the Cargo and build-script settings before changing assist or cache options. For adjacent user tasks, read the rust-analyzer installation, VS Code and editor integration, feature, and troubleshooting pages.