Odel
rrubocop

rrubocop

Local
@adrianovRustGPL-3.0Updated 2 days ago

Fast RuboCop-compatible Ruby linter with MCP inspect and autocorrect tools.

rrubocop

10x faster RuboCop drop-in — same CLI, .rubocop.yml, and offense output, without maintaining RuboCop gems. Linting and simple config need no Ruby; complex ERB still does. Point it at an existing project and use it like RuboCop.

One binary — runs the same way regardless of rbenv, rvm, system Ruby, or Docker. Uses tree-sitter; no Ruby runtime required for linting or simple ERB. Unsupported ERB falls back to ruby / bundle exec ruby.

Drop-in parity: reads your existing .rubocop.yml, emits RuboCop-like text/JSON, supports -a/-A autocorrect, and grows cop coverage over time.

Baseline (shown in --help / --version): rubocop 1.84.2 with rubocop-rails 2.34.3, rubocop-performance 1.26.1, rubocop-rspec 3.9.0, rubocop-rspec_rails 2.32.0, rubocop-factory_bot 2.28.0 — pinned in src/resources/baseline.json.

Parity runs have been verified over 600+ installed Ruby gem projects (RuboCop vs rrubocop on the same trees).

Install

brew install adrianov/rrubocop/rrubocop
cargo install rrubocop

macOS (.tar.gz from GitHub Releases; binary + man):

# Apple Silicon — use the *-x86_64-apple-darwin.tar.gz asset on Intel Macs
curl -LO https://github.com/adrianov/rrubocop/releases/download/v0.8.3/rrubocop-0.8.3-aarch64-apple-darwin.tar.gz
tar -xzf rrubocop-0.8.3-aarch64-apple-darwin.tar.gz
sudo cp rrubocop-0.8.3-aarch64-apple-darwin/rrubocop /usr/local/bin/
sudo mkdir -p /usr/local/share/man/man1
sudo cp rrubocop-0.8.3-aarch64-apple-darwin/rrubocop.1 /usr/local/share/man/man1/

Ubuntu / Debian (.deb from GitHub Releases; amd64, Ubuntu 22.04+ / Debian bookworm+):

# example for v0.8.3 — use the asset name from the release page
curl -LO https://github.com/adrianov/rrubocop/releases/download/v0.8.3/rrubocop_0.8.3-1_amd64.deb
sudo dpkg -i rrubocop_0.8.3-1_amd64.deb
man rrubocop
rrubocop [OPTIONS] [PATH]...

Features

  • Config — RuboCop-compatible resolution: walk-up discovery, inherit_from / inherit_gem / require/plugins, inherit_mode (merge/override), nested .rubocop.yml overrides, DisabledByDefault, NewCops / Enabled: pending, plus per-cop Enabled / Exclude / Include / options; public gem defaults/inherit_gem YAML are vendored by version (from Gemfile.lock, with same_as aliases when YAML is identical) and parsed in memory; private/unlisted gems fall back to bundle info --path; simple ERB in YAML expands natively (Ruby only for unsupported tags)
  • Autocorrect-a (safe) / -A (all)
  • Outputprogress (marks stream as files finish), text, json, github, quiet, files, … (TTY color like RuboCop; --color / --no-color)
  • Directives# rubocop:disable / enable
  • Parser — tree-sitter-ruby (no Prism / no CRuby)
  • Cache — content-addressed cache.redb under $RRUBOCOP_CACHE_DIR or $XDG_CACHE_HOME/rrubocop / ~/.cache/rrubocop (same style as abcop); --cache false skips reads but still writes
  • MCPrrubocop --mcp starts a Model Context Protocol server (official Rust rmcp SDK) with the same tools as RuboCop 1.85+: rubocop_inspection and rubocop_autocorrection

Reference implementations: nitrocop (architecture & fixtures), upstream RuboCop.

Built-in cops

Departments grow breadth-first from common RuboCop plugin sets (nitrocop / gem sources). Notable coverage:

DepartmentNotes
Layout/*90 layout cops (alignment, spacing, empty lines, indentation; all with autocorrect)
Lint/*, Style/*, Naming/*, Security/*69 / 143 / 9 / 4
Metrics/*AbcSize, BlockNesting, ClassLength, CollectionLiteralLength, ModuleLength, ParameterLists
Rails/*62 rails cops
Performance/*24 performance cops
RSpec/*104 rspec cops
RSpecRails/*2 (HttpStatus, InferredSpecType)
FactoryBot/*4 (AssociationStyle, AttributeDefinedStatically, CreateList, FactoryClassName)
Bundler/*, Gemspec/*, Rake/*4 / 4 / 5
GraphQL/*26 rubocop-graphql cops

Use rrubocop --list-cops for the full registered set, and rrubocop --list-autocorrectable-cops for cops with -a/-A support (180 with autocorrect so far; Layout complete; Style/Lint/Rails/RSpec growing).

Usage

rrubocop                         # lint .
rrubocop app lib                 # paths
rrubocop -f json .               # JSON offenses
rrubocop -a .                    # safe autocorrect
rrubocop -A .                    # all autocorrect
rrubocop --only Metrics/AbcSize lib
rrubocop --list-cops
rrubocop -L                      # list target files
rrubocop -F 10                   # stop after 10 offenses (off by default; `-F` = 1)
                                 # with `-a`/`-A`, N is non-autocorrectable offenses only
rrubocop --mcp                   # MCP server on stdio (for AI clients)

Exit codes: 0 clean, 1 offenses at/above --fail-level, 2 error.

MCP (Model Context Protocol)

rrubocop --mcp runs a long-lived MCP server on stdio — same idea as RuboCop’s MCP, with no Ruby mcp gem. Tools:

ToolPurpose
rubocop_inspectionLint via path and/or inline source_code; returns LSP-shaped offense JSON
rubocop_autocorrectionAutocorrect (safety: true = safe only; false = all); writes files when path is set
  • MCP Registry name: mcp-name: io.github.adrianov/rrubocop

Metadata lives in server.json (Cargo package on crates.io). Each v* tag publishes that listing to the MCP Registry.

Example client config (Cursor / VS Code / Windsurf):

{
  "mcpServers": {
    "rrubocop": {
      "type": "stdio",
      "command": "rrubocop",
      "args": ["--mcp"],
      "cwd": "/path/to/your/project"
    }
  }
}

Claude Code:

claude mcp add rrubocop -- rrubocop --mcp

Intended for MCP clients, not interactive use.

Caching

Content-addressed cache under $RRUBOCOP_CACHE_DIR (or $XDG_CACHE_HOME/rrubocop / ~/.cache/rrubocop). Keys cover contents, version, rule revision, --only/--except, config fingerprint, and path. Auto-pruned to 20 000 entries; --cache false skips reads but still writes. Autocorrect runs bypass the cache. Nothing is written inside the project.

Benchmarks

Cold lint (cache off) on a large Rails codebase (~3.8k Ruby files), same host:

ToolWall clockResultNotes
bundle exec rubocop --cache false2m 37s (2:36.64)0 offenses~99% CPU (mostly single-core)
rrubocop --cache false7.0s (7.005)0 offenses~1040% CPU (parallel)
nitrocop --no-cache8.9s (8.906)~21k offenses~1000% CPU; not a fair parity run (see below)

rrubocop is ≈ 22× faster wall clock than RuboCop (156.6s / 7.0s) on the same clean result. RuboCop user time was 155s; rrubocop used 71s of CPU across cores.

nitrocop caveat: out of the box it did not honor the same disabled cops / custom rules / gem configs as bundle exec rubocop (e.g. failed inherit_gem load, skipped/unimplemented cops), so it reported ~21k false positives vs RuboCop/rrubocop’s clean run. Matching that baseline needs extra setup (--migrate, plugin/config wiring). Treat the 8.9s figure as raw throughput only, not drop-in parity.

Cold lint (cache off) on rails/rails (main, RuboCop 1.79.2 via bundle exec), same host (4 cores), both clean (0 offenses). Two runs averaged:

ToolWall clockNotes
bundle exec rubocop --cache false1m 7s (67.254)~99% CPU (mostly single-core); 3543 files
rrubocop --cache false5.7s (5.668)~357% CPU (parallel); 3446 files

12× faster wall clock (67.254s / 5.668s). RuboCop user time was 66.9s; rrubocop used 20.2s of CPU across cores.

Same host, cold --cache false, offense-set parity on Active Support and Active Record (fp=0, fn=0 on shared .rb files):

TargetRuboCoprrubocopSpeedup
activesupport (rails main)11.566s (531 files)1.872s≈6.2×
activerecord (rails main)29.611s (1162 files)2.780s≈10.7×
activesupport (v8.1.3.1)10.729s (506 files)1.795s≈6.0×
activerecord (v8.1.3.1)27.847s (1126 files)2.656s≈10.5×

Cold lint on a fresh rails new app (Rails 8.1.3.1, default rubocop-rails-omakase via inherit_gem, RuboCop 1.90.0 via bundle exec), plus scaffold/model/mailer/job generators (41 identical target files). Offense-set parity fp=0, fn=0 (both clean). Two-run average:

ToolWall clock
bundle exec rubocop --cache false0.722s
rrubocop --cache false0.593s

Cross-test vs nitrocop

With a local nitrocop build:

testdata/cross_test_nitrocop.py /path/to/fixture_dir

Compares (path, line, cop_name) offense sets.

License

GPL-3.0-or-later. See NOTICE for MIT attribution of nitrocop-derived design/logic.