Back to Scaling Ruby Applications guides

Getting Started with Rufo

Stanley Ulili
Updated on September 24, 2025

When Ruby projects grow from solo work to team collaboration, consistent code style becomes critical. Rufo is a fast, opinionated formatter that automatically standardizes your code and eliminates the hassle of manual formatting.

With its pragmatic approach to spacing, indentation, and structure, Rufo keeps code clean and readable without the complexity of heavy linters.

This guide walks through installation, usage, and integration into your Ruby workflow.

Prerequisites

To work through this guide, you'll need Ruby 2.4 or later installed:

 
ruby --version
Output
ruby 3.4.5 (2025-07-16 revision 20cda200d3) +PRISM [arm64-darwin24]

This guide assumes basic familiarity with Ruby syntax, command-line tools, and common development practices. You should understand concepts like gems, bundler, and basic project structure.

Understanding Rufo's formatting approach

Rufo operates on the principle of minimal, consistent formatting changes that enhance readability without altering code behavior. Rather than enforcing strict style guidelines, it makes practical decisions about spacing and structure.

The formatter handles several key formatting areas:

  • Spacing consistency: Standardizes spaces around operators, commas, and method calls
  • Indentation alignment: Ensures consistent two-space indentation throughout files
  • Line breaking logic: Applies intelligent line breaks for long expressions and method chains
  • String formatting: Maintains existing quote styles while fixing spacing issues
  • Method definition structure: Aligns parameters and method bodies consistently

Create a project directory to explore Rufo's formatting behavior:

 
mkdir rufo-formatting-demo && cd rufo-formatting-demo

Installing and basic usage

Rufo installs as a standard Ruby gem and works immediately without configuration files or complex setup procedures. The tool provides both command-line formatting and programmatic access for automation.

Create a Gemfile for your project:

 
bundle init

Add Rufo to your project's Gemfile for team consistency:

Gemfile
source 'https://rubygems.org'

gem 'rufo', '~> 0.18.0', require: false

Install project dependencies:

 
bundle install
Output
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching rufo 0.18.1
Installing rufo 0.18.1
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

Create a sample Ruby file with inconsistent formatting to demonstrate Rufo's capabilities:

sample_code.rb
class UserProcessor
def initialize(name,email,age)
@name=name
@email = email
@age= age
end

def process_user( )
result={
:name=>@name,
:email => @email,
"age"=>@age,
:processed_at=>Time.now
}

if valid_email?(@email)&&@age>=18
result[:status]="approved"
else
result[ :status ] = "pending"
end

return result
end

private

def valid_email?(email)
email.include?("@")&&email.length>5
end
end

processor=UserProcessor.new("John Doe","john@example.com",25)
puts processor.process_user()

This code demonstrates common formatting inconsistencies: irregular spacing around operators, mixed indentation, inconsistent hash syntax, and variable spacing in method calls.

Run Rufo to see the formatted output:

 
bundle exec rufo sample_code.rb
Output
Formatting sample_code.rb

Check the formatted result:

sample_code.rb
class UserProcessor
  def initialize(name, email, age)
    @name = name
    @email = email
    @age = age
  end

  def process_user()
    result = {
      :name => @name,
      :email => @email,
      "age" => @age,
      :processed_at => Time.now,
    }

    if valid_email?(@email) && @age >= 18
      result[:status] = "approved"
    else
      result[:status] = "pending"
    end

    return result
  end

  private

  def valid_email?(email)
    email.include?("@") && email.length > 5
  end
end

processor = UserProcessor.new("John Doe", "john@example.com", 25)
puts processor.process_user()

Rufo automatically corrected spacing issues, aligned method parameters, standardized indentation, and improved hash formatting while preserving the original logic and functionality.

Notice how Rufo maintained the existing hash syntax (:name => value) rather than converting to modern syntax (name: value). This demonstrates Rufo's conservative approach that prioritizes consistency over style enforcement.

Command-line usage and options

Rufo provides several command-line options that control formatting behavior and output modes. These options help integrate Rufo into different development workflows and automation scenarios.

Checking formatting without changes

Use the --check flag to verify formatting without modifying files:

 
bundle exec rufo --check sample_code.rb

If the file is already formatted correctly, Rufo exits silently with status code 0. For files that need formatting, it exits with status code 1 and shows which files require changes.

Create an unformatted file to demonstrate check mode:

unformatted.rb
def messy_method(x,y,z)
return x+y*z
end

Check formatting status:

 
bundle exec rufo --check unformatted.rb
Output
Formatting unformatted.rb produced changes

The output indicates that unformatted.rb needs formatting. The --check mode proves valuable in continuous integration environments where you want to enforce formatting standards without automatically modifying code.

Processing multiple files and directories

Rufo can format entire directories recursively, making it easy to standardize formatting across large codebases:

 
mkdir lib test
 
echo 'def test_method(a,b); a+b; end' > lib/calculator.rb
 
echo 'class TestCase; def setup; @data={}; end; end' > test/test_helper.rb

Format all Ruby files in the current directory and subdirectories:

 
bundle exec rufo .
Output
Format: ./Gemfile
Format: ./lib/calculator.rb
Format: ./test/test_helper.rb
Format: ./unformatted.rb

This recursive formatting ensures consistent code style across your entire project structure without requiring manual file-by-file processing.

Integrating Rufo into your workflow

Running Rufo manually works for small demos, but real projects benefit from automation. By integrating Rufo into your editor, pre-commit hooks, or CI pipeline, you ensure consistent formatting without relying on developers to remember to run it.

Editor integration

Most popular editors like VS Code, RubyMine, and Vim support Rufo through extensions or plugins. With these integrations, files are automatically formatted on save, providing instant feedback and eliminating formatting debates during code review.

Git hooks

You can use Overcommit or custom Git hooks to run Rufo before each commit:

 
#!/bin/sh
bundle exec rufo --check .
if [ $? -ne 0 ]; then
  echo "Rufo formatting required. Run 'bundle exec rufo .' before committing."
  exit 1
fi

This prevents unformatted code from ever entering your repository.

Continuous integration

Add Rufo checks to your CI pipeline to enforce formatting standards across your team. A simple bundle exec rufo --check . step ensures that pull requests meet your project’s consistency requirements.

Final thoughts

Rufo provides consistent Ruby code formatting with minimal setup. It preserves existing structure while fixing spacing, indentation, and readability issues, making it a practical tool for both individuals and teams.

Its speed and simplicity make it well suited for large codebases where other formatters may add unnecessary complexity. Integrating Rufo through the CLI, editor plugins, or Git hooks ensures consistent style without the overhead of rule management.

Explore the Rufo documentation for detailed usage patterns and integration examples.