Question

Ruby require vs require_relative: Differences and Usage

rubyrequire

Question

What is the difference between require and require_relative in Ruby, and when should each method be used?

Short Answer

By the end of this page, you will understand how Ruby locates files with require and require_relative, why the current working directory can cause loading bugs, and how to choose the right method for project files and external libraries.

Concept

require and require_relative both load Ruby code from another file. The important difference is where Ruby looks for that file.

  • require searches Ruby's load path, stored in $LOAD_PATH.
  • require_relative finds a file relative to the file that contains the call.

require is usually used for Ruby standard-library features, gems, and other dependencies made available on the load path:

require "json"
require "date"

require_relative is usually used for files that belong to your own application:

require_relative "models/user"

This distinction matters because a program can be started from different directories. A path based on the current working directory may work in one terminal command and fail in another. require_relative avoids that problem by anchoring the path to the source file itself.

Both methods normally load a feature only once during a Ruby process. Ruby records loaded features in $LOADED_FEATURES, so calling the same require again usually does not execute the file a second time.

Mental Model

Imagine your project is a set of folders in a building.

  • require says: “Ask the building directory for a room named json.” Ruby checks the directories listed in $LOAD_PATH.
  • require_relative says: “Start in this file's room, then walk to the nearby room named models/user.”

For a library such as json, using the building directory makes sense. For a nearby project file, starting from the current source file is more reliable than relying on where someone happened to start the program.

Take Quiz

Syntax and Examples

require loads a feature found through $LOAD_PATH.

require "json"

puts JSON.generate({ name: "Ava" })

Ruby finds the json library because it is part of the standard library and is available through Ruby's load path.

require_relative loads a path relative to the current source file.

Suppose the project has this structure:

my_app/
├── app.rb
└── greeting.rb

greeting.rb:

class Greeting
  def self.message(name)
    "Hello, #{name}!"
  end
end

app.rb:

require_relative "greeting"

puts Greeting.message("Mina")

Ruby treats "greeting" as a path next to app.rb. The .rb extension is optional in typical Ruby source-file imports:

require_relative "greeting"
# Equivalent for this use case:
require_relative "greeting.rb"

You can also navigate directories:

require_relative "../lib/formatter"

Step by Step Execution

Consider this project:

inventory/
├── lib/
│   └── formatter.rb
└── bin/
    └── report.rb

lib/formatter.rb:

module Formatter
  def self.price(amount)
    format("$%.2f", amount)
  end
end

bin/report.rb:

require_relative "../lib/formatter"

price = 12.5
puts Formatter.price(price)

Execution proceeds as follows:

  1. Ruby begins running bin/report.rb.
  2. It reaches require_relative "../lib/formatter".
  3. Ruby starts from the directory containing report.rb, which is bin/.
  4. It follows ../lib/formatter, reaching lib/formatter.rb.
  5. Ruby executes formatter.rb, which defines the Formatter module.
  6. Control returns to report.rb.
  7. Formatter.price(12.5) returns "$12.50".
  8. The program prints:
$12.50

This works whether you run the program from inventory/, its parent directory, or another location, because the relative path is based on report.rb, not the shell's current directory.

Real World Use Cases

  • Standard library: Load built-in features such as json, csv, date, pathname, or net/http with require.

    require "csv"
    
  • Gems: Load code installed by Bundler or RubyGems with require.

    require "rails"
    require "rspec"
    
  • Small scripts: Load helper files next to a script with require_relative.

    require_relative "config"
    
  • Application internals: Load models, services, and utilities using stable paths within a project.

    require_relative "services/email_sender"
    
  • Command-line tools: A file under bin/ can reliably load code from lib/.

    require_relative "../lib/my_tool"
    
Take Quiz

Real Codebase Usage

In a well-structured Ruby project, developers generally separate dependency loading from internal file loading.

# lib/order_processor.rb
require "json"                         # Standard library or gem
require_relative "services/tax_service" # This project's file
require_relative "models/order"         # This project's file

Common patterns include:

  • Entrypoint files load dependencies first. A CLI, web server, or background-job process often has one entry file that requires external libraries and initializes the app.

  • Internal files use stable local paths. require_relative prevents accidental dependence on the command used to launch Ruby.

  • Libraries expose one public entry file. A gem commonly has a file such as lib/my_gem.rb that uses require_relative to load its internal components.

    # lib/my_gem.rb
    require_relative "my_gem/version"
    require_relative "my_gem/client"
    
  • Frameworks may autoload files. In Rails applications, many application classes are loaded automatically by the framework. Do not add require_relative everywhere just because it is Ruby; follow the framework's loading conventions.

  • Avoid changing $LOAD_PATH casually. Adding project folders to $LOAD_PATH can make require work for local files, but it hides where dependencies come from and can create name collisions. Prefer require_relative for direct internal relationships.

Common Mistakes

Assuming require searches relative to the current file

This can fail when the program is launched from a different directory:

# bin/report.rb
require "lib/formatter"

require searches $LOAD_PATH; it does not automatically search beside report.rb.

Use require_relative for this project path instead:

require_relative "../lib/formatter"

Confusing the current working directory with the current file directory

A path beginning with ./ in require refers to the process's current working directory, not necessarily the directory of the Ruby file containing the statement:

require "./config/settings"

This can be valid, but it is sensitive to how the program was started. Use require_relative "config/settings" when you mean “next to this source file.”

Using require_relative for gems

This is usually incorrect:

require_relative "json"

Ruby will look for a local file named json relative to the current source file. Use:

require "json"

Loading the same code in inconsistent ways

Avoid mixing paths for the same file:

require_relative "helper"
require "./helper"

Different path forms can make code harder to reason about and may lead to unexpected loading behavior. Choose one consistent approach.

Expecting changed files to reload automatically

require and require_relative normally load a feature once per process. Editing the file while the program is still running does not cause it to run again. Restart the process during normal development, or use a deliberate reloading mechanism supplied by your framework.

Comparisons

Featurerequirerequire_relative
Main lookup locationDirectories in $LOAD_PATHDirectory of the source file containing the call
Best forStandard library, gems, configured librariesFiles within the same project
Depends on launch directorySometimes, especially with ./pathNo
Examplerequire "json"require_relative "models/user"
Typical extension usageUsually omit .rbUsually omit .rb

require versus load

Behaviorrequire / require_relativeload
Loads a file once by defaultYesNo, it executes every time
Common purposeImport dependenciesRare cases needing intentional re-execution
Recommended for normal application codeYesUsually no

For normal Ruby programs, use require or require_relative. load is not a replacement for either one.

Take Quiz

Cheat Sheet

# Standard library or gem
require "json"
require "my_gem"

# A file next to the current source file
require_relative "helper"

# A file in a sibling or parent directory
require_relative "../lib/formatter"
  • require searches $LOAD_PATH.

  • require_relative starts from the directory of the file containing the call.

  • Use require for gems and standard-library code.

  • Use require_relative for known files inside your project.

  • .rb is usually optional.

  • Both normally execute a loaded feature only once per Ruby process.

  • require "./file" is based on the current working directory, not the caller file's directory.

  • Inspect Ruby's load path when debugging:

    puts $LOAD_PATH
    

FAQ

Should I use require or require_relative for files in my Ruby project?

Use require_relative when the file is a direct project file and you know its location relative to the current source file. Use require when the project is intentionally configured as a library on $LOAD_PATH.

Does require_relative search $LOAD_PATH?

No. It resolves the given path relative to the file that calls require_relative.

Why does require "./file" work sometimes but not always?

It is resolved from the process's current working directory. If you launch Ruby from a different directory, the same path may no longer point to the file you expected.

Do I need to write .rb in require_relative?

Usually no. Ruby normally finds "helper" as helper.rb. Including .rb is also valid for regular Ruby source files.

Can I require the same file twice?

You can call require or require_relative twice, but Ruby normally loads the feature only the first time. The later calls return false instead of re-executing it.

What does require return?

It returns true when it loads a feature for the first time and false when that feature was already loaded.

Why can't Ruby find a gem with require?

Ensure the gem is installed and available in the active Ruby environment. In Bundler-managed projects, start the program with Bundler, such as bundle exec ruby app.rb, when appropriate.

Does Rails require me to use require_relative for models and controllers?

Usually no. Rails commonly autoloads application code according to its conventions. Use explicit requires only where the framework or project setup calls for them.

Take Quiz

Mini Project

Description

Build a small command-line order summary with files separated into a bin entrypoint and reusable lib code. The project demonstrates loading external Ruby functionality with require and nearby application files with require_relative.

Goal

Run a report script that loads a local formatter module and prints a JSON order summary.

Requirements

Create a lib/formatter.rb file that formats a price as currency. Create a bin/order_report.rb entrypoint file. Use require_relative to load the formatter from the lib directory. Use require to load Ruby's json library. Print an order summary as formatted JSON.

Take Quiz

Keep learning

Related questions

View more