123456789_123456789_123456789_123456789_123456789_

This guide will get you up and running with RuboCop in a few minutes. RuboCop serves three primary roles:

  1. Code style checker (a.k.a. linter) — enforces style conventions from the Ruby Style Guide

  2. Lint tool — catches bugs and suspicious code, like a smarter <code>ruby -w</code>

  3. Code formatter — automatically fixes layout and formatting

First Run

After installing RuboCop, just run it from your project’s root directory:

$ rubocop

RuboCop will recursively check all Ruby files and report any offenses it finds:

Inspecting 5 files
{.W}.C.

Offenses:

lib/foo.rb:2:3: C: Style/IfUnlessModifier: Favor modifier if usage when having a single-line body.
  if something
  ^^
lib/bar.rb:5:5: W: Lint/UselessAssignment: Useless assignment to variable - x.
    x = 42
    ^

5 files inspected, 2 offenses detected

Each offense shows the file, line, column, severity (C for convention, W for warning, E for error), the cop name, and a description. The letter on the progress line (. = clean, C/W/E = offense found) gives you a quick overview.

Setting Up Your Project

For an existing project with many offenses, the easiest way to get started is to generate a TODO file:

$ rubocop --auto-gen-config

This creates two files:

  • <code>.rubocop_todo.yml</code> — temporarily disables all current offenses

  • <code>.rubocop.yml</code> — your configuration file (with <code>inherit_from: .rubocop_todo.yml</code> added)

Now rubocop will pass cleanly, and you can work through the TODO entries at your own pace. See Auto-generating Configuration for details.

For a new project, you can generate a starter config file instead:

$ rubocop --init

Customizing RuboCop

All configuration lives in <code>.rubocop.yml</code>. Here are a few common adjustments:

# Increase the maximum line length
Layout/LineLength:
  Max: 120

# Disable a cop entirely
Style/Documentation:
  Enabled: false

# Restrict a cop to specific files
Rails/HasAndBelongsToMany:
  Include:
    - app/models/**/*.rb

See Configuration for the full reference.

Fixing Offenses Automatically

Many cops can autocorrect the problems they find. Use <code>-a</code> for safe corrections only, or <code>-A</code> to include unsafe ones:

# Safe autocorrections only
$ rubocop -a

# All autocorrections (safe and unsafe)
$ rubocop -A

# Fix only formatting (layout) offenses
$ rubocop -x
Tip
Review the diff after running autocorrect, especially with <code>-A</code>. See Autocorrect for more details on safe vs. unsafe corrections.

Inspecting Only What Changed

On a large project you often care only about the code you just touched. <code>--changed</code> asks git which files differ and inspects those:

# Files you have modified since the last commit, including untracked ones
$ rubocop --changed

# Files your branch changed since it forked from main
$ rubocop --changed=main...

The revision goes straight to <code>git diff</code>, so it means what it means there. <code>--changed=main</code> compares the working tree against the tip of main, which also picks up every file main changed after your branch forked from it. The three-dot form <code>main…​</code> compares against the merge base instead, but it stops at your last commit: uncommitted edits to tracked files are left out, though untracked files still count. That makes it the one to use on CI, where the checkout is clean anyway.

Deleted files are skipped, and Include/Exclude still apply, so the result is the intersection of "what git says changed" and "what RuboCop would inspect anyway". Paths given on the command line narrow it further, so <code>rubocop --changed lib</code> inspects the changed files under lib.

Two things it is good for. On a large codebase that is mid-adoption, it keeps a local run fast and focused on the code you are actually touching:

$ rubocop --changed --diff

And on CI, it holds new code to a standard the whole repository does not meet yet, without a todo file:

$ git fetch origin main
$ rubocop --changed=origin/main...

Finding the merge base takes history from both branches, so a shallow clone (the default for many CI checkouts) has to be deepened first, or git fails with <code>no merge base</code>.

Note
The whole file is inspected, not just the lines that changed, so a file you touched can still report an offense from a part you did not write. Tools like Pronto exist for line-level filtering.

In a repository without any commits every file counts as changed, and outside a git repository <code>--changed</code> reports the error rather than guessing.

Editor Integration

For the best experience, set up RuboCop in your editor so you get real-time feedback as you type. RuboCop has a built-in LSP server that works with any editor that supports the Language Server Protocol.

The recommended setup for popular editors:

  • VS Code — Install the Ruby LSP extension

  • Emacs — Use Eglot (built-in since Emacs 29) or lsp-mode

  • Vim/Neovim — Use the built-in LSP client or ALE

See Integration with Other Tools for more editors and alternative approaches.

Next Steps

  • CLI Reference — full command-line reference with all flags

  • Configuration — everything about <code>.rubocop.yml</code>

  • Source Code Directives — disable/enable cops inline with comments

  • Cops — browse all available cops by department

  • Plugins — add cops for Rails, RSpec, Performance, and more