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.
requiresearches Ruby's load path, stored in$LOAD_PATH.require_relativefinds 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.
requiresays: “Ask the building directory for a room namedjson.” Ruby checks the directories listed in$LOAD_PATH.require_relativesays: “Start in this file's room, then walk to the nearby room namedmodels/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.
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:
- Ruby begins running
bin/report.rb. - It reaches
require_relative "../lib/formatter". - Ruby starts from the directory containing
report.rb, which isbin/. - It follows
../lib/formatter, reachinglib/formatter.rb. - Ruby executes
formatter.rb, which defines theFormattermodule. - Control returns to
report.rb. Formatter.price(12.5)returns"$12.50".- 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, ornet/httpwithrequire.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 fromlib/.require_relative "../lib/my_tool"
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_relativeprevents 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.rbthat usesrequire_relativeto 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_relativeeverywhere just because it is Ruby; follow the framework's loading conventions. -
Avoid changing
$LOAD_PATHcasually. Adding project folders to$LOAD_PATHcan makerequirework for local files, but it hides where dependencies come from and can create name collisions. Preferrequire_relativefor 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
| Feature | require | require_relative |
|---|---|---|
| Main lookup location | Directories in $LOAD_PATH | Directory of the source file containing the call |
| Best for | Standard library, gems, configured libraries | Files within the same project |
| Depends on launch directory | Sometimes, especially with ./path | No |
| Example | require "json" | require_relative "models/user" |
| Typical extension usage | Usually omit .rb | Usually omit .rb |
require versus load
| Behavior | require / require_relative | load |
|---|---|---|
| Loads a file once by default | Yes | No, it executes every time |
| Common purpose | Import dependencies | Rare cases needing intentional re-execution |
| Recommended for normal application code | Yes | Usually no |
For normal Ruby programs, use require or require_relative. load is not a replacement for either one.
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"
-
requiresearches$LOAD_PATH. -
require_relativestarts from the directory of the file containing the call. -
Use
requirefor gems and standard-library code. -
Use
require_relativefor known files inside your project. -
.rbis 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.
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.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.