Kernel#require
require(name) -> true or false require loads and executes the named Ruby source file. It’s the primary mechanism for loading external Ruby code, including standard library modules, gems, and your own files. If the named file has already been loaded, require returns false to prevent double-loading.
Syntax
require "filename"
require "path/to/filename"
require "gem_name"
The argument to require is almost always a string literal, though any expression that evaluates to a string will work. Ruby resolves the name using the entries in $LOAD_PATH, trying each directory in order until it finds a matching file or gives up with a LoadError. This resolution happens at runtime, which is why require can load files conditionally based on environment or configuration.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name | String | — | The name of the file, gem, or library to load. Can be a relative path, absolute path, or gem name. |
Examples
Loading a standard library file
require "json"
json_string = '{"name": "Alice", "age": 30}'
parsed = JSON.parse(json_string)
# => {"name"=>"Alice", "age"=>30}
# Calling require again returns false
require "json"
# => false
Calling require a second time returns false without re-executing the file, which is the mechanism that prevents double-loading. Ruby tracks every successfully loaded file in the $LOADED_FEATURES array and skips any name that already appears there. This is transparent to the caller — you can safely place a require in multiple files that might be loaded together without worrying about side effects from repeated execution.
Loading a gem
require "httparty"
response = HTTParty.get("https://example.com")
# Makes an HTTP GET request using the httparty gem
When you require a gem, Ruby searches the gem paths configured in your environment rather than the ordinary $LOAD_PATH. This keeps gem code separate from your project files and standard library code, which is one reason require "json" and require "./my_module" can coexist without confusion.
Loading a local file
# Assume ./my_module.rb contains: def greet; "Hello!"; end
require "./my_module"
greet
# => "Hello!"
Loading a local file with ./ tells Ruby to look relative to the current working directory, which works for simple scripts but can break when the program is run from a different location. For project code in a known directory structure, require_relative anchors the path to the calling file instead of the process working directory, keeping the dependency stable regardless of how the program is launched.
Common Patterns
Using require_relative for local files
require_relative loads files relative to the current file’s location, useful for loading project-local modules:
# In lib/my_app/helpers.rb
require_relative "utils" # Loads lib/my_app/utils.rb
require_relative resolves paths relative to the file that contains the call, not relative to the working directory or the load path. This makes it the preferred choice for project-internal files because the path stays correct regardless of how the program is launched or which directory the user ran it from.
Conditional loading
# Only load optional dependency if available
begin
require "nokogiri"
# Use Nokogiri for XML parsing
rescue LoadError
# Fall back to REXML or skip XML features
end
Conditional loading around a begin/rescue block is a standard pattern for optional dependencies. It lets the program degrade gracefully when a gem is not installed, which is especially useful in libraries that support multiple backends or file formats without forcing users to install every possible dependency.
Loading multiple files at once
# Load several files in one call (Ruby 3.0+)
require "json", "yaml", "csv"
Ruby 3.0 added the ability to pass multiple names to a single require call, which cuts down on repetition when several libraries are needed at the top of a file. The behaviour is the same as calling require once per name: each file is loaded at most once, and the order follows the argument list.
Load Path
Ruby searches for files in the $LOAD_PATH (also accessible as $:) array:
# See where Ruby looks for files
$LOAD_PATH.each { |path| puts path }
# Add a custom directory to the load path
$LOAD_PATH.unshift("/path/to/my/library")
Errors
| Error | When it occurs |
|---|---|
LoadError | The specified file cannot be found in the load path |
LoadError | The gem is not installed |
SyntaxError | The loaded file contains invalid Ruby syntax |
loading code on demand
require is one of the core tools for shaping a Ruby program into small files that are loaded when needed. That keeps startup logic clear and makes dependencies easy to see near the top of the file. It also protects against loading the same source twice, which is useful when several paths can reach the same helper. For local project files, the choice between require and require_relative should make the path relationship obvious to the reader.
The method also gives the project a single place to describe what pieces are needed before the rest of the code can run. That helps when the file list grows, because the dependencies stay grouped together and the loading order is easier to reason about. In that sense, require is not just a loader; it is part of the structure that keeps a Ruby application easy to navigate.
For larger projects, that structure can help separate stable helpers from code that is only needed in certain entry points. The top of the file becomes a quick map of the program’s dependencies, which makes onboarding and maintenance easier. A clear load list also makes it more obvious when a file is doing too much and should be split into smaller pieces.
That same clarity is useful when a library grows across several directories. A well-placed require line tells the reader where the code expects its building blocks to come from and which features are required before execution continues. In practice, that makes the file layout easier to trust and reduces the chance that a hidden dependency will surprise the next person who opens the project.
It also encourages a habit of loading only what the current file actually needs. That keeps startup work focused and makes the program easier to inspect when something fails during boot. A short, explicit list of requirements can tell a lot about a file’s responsibilities before the reader even reaches the main logic.
That same habit makes refactors easier because the dependencies stay visible in one place. When a helper moves or a feature is removed, the load list shows what should change with it. In that way, require helps the file stay tidy over time, not just at the moment it first loads.