Question
How to Use a Local Gem in a Gemfile with Bundler (Ruby)
Question
I want Bundler to use a gem from a local folder instead of downloading it from RubyGems. Is there a supported way to specify a local gem in a Gemfile, or would I need to move the gem's directory into .bundle?
Short Answer
By the end of this page, you will understand how Bundler can load a gem from a local path, how to write that in a Gemfile, when to use it during development, and what mistakes to avoid when working with local gems in Ruby projects.
Concept
Bundler lets you define where gems come from. Most of the time, gems are fetched from sources like RubyGems, but Bundler can also load a gem directly from a local directory.
This is useful when:
- you are developing a gem and an app at the same time
- you want to test unpublished changes locally
- you need to work on multiple related Ruby projects together
The main idea is that a gem entry in a Gemfile does not have to come only from a remote server. It can also come from:
- a local path
- a Git repository
- a standard gem source such as RubyGems
For a local gem, Bundler uses the :path option.
gem 'my_gem', path: '../my_gem'
This tells Bundler:
- the gem is named
my_gem - Bundler should look for it in
../my_gem - it should use the gemspec found there instead of downloading from RubyGems
You do not need to move the gem into .bundle. The .bundle directory is not where you manually place gem source code for normal Bundler usage. Instead, you point Bundler to the folder where the gem already exists.
Why this matters in real programming:
- it speeds up local development
- it makes gem changes immediately available to the app using them
- it supports monorepos and side-by-side project development
- it avoids publishing test versions of gems just to try local changes
Mental Model
Think of Bundler as a package manager with a delivery address book.
Usually, you tell it:
- "Get this gem from the public store"
With a local gem, you tell it:
- "Do not order this from the store. Pick it up from this folder on my computer."
The :path option is that pickup address.
So instead of searching online, Bundler walks to that local folder, reads the gemspec, and uses that gem directly.
Syntax and Examples
The basic syntax is:
gem 'gem_name', path: 'relative/or/absolute/path'
Example: local gem next to your app
Suppose your folders look like this:
projects/
my_app/
Gemfile
my_gem/
my_gem.gemspec
In my_app/Gemfile:
source 'https://rubygems.org'
gem 'my_gem', path: '../my_gem'
Then run:
bundle install
Bundler will use the gem from ../my_gem.
Example: multiple local gems
source 'https://rubygems.org'
gem 'billing_core', path: '../billing_core'
gem 'shared_utils', path: '../shared_utils'
Example: using a path block
Bundler also supports grouping gems from the same local folder base:
Step by Step Execution
Consider this Gemfile:
source 'https://rubygems.org'
gem 'my_gem', path: '../my_gem'
And assume ../my_gem contains my_gem.gemspec.
What happens step by step
- Bundler reads the
Gemfile. - It sees that
my_gemhas a:pathoption. - Instead of checking RubyGems, Bundler looks in
../my_gem. - It reads the gemspec in that folder.
- It resolves the gem's dependencies from the gemspec.
- It records the local path source in
Gemfile.lock. - Your Ruby app can now
requirethat gem like a normal dependency.
Small example
my_gem/lib/my_gem.rb
module MyGem
def self.greet
'Hello from local gem'
Real World Use Cases
1. Developing an app and gem together
You may maintain a Rails app and a shared internal gem at the same time. Using :path lets you update the gem and test changes immediately.
2. Testing unpublished features
Before releasing a gem version, you can try the new code locally inside a real application.
3. Monorepo or multi-repo development
Companies often keep reusable libraries in nearby directories. Path-based gems make local integration easier.
4. Internal tools and private code
Some gems are not published publicly. A local path can be useful during setup or internal development.
5. Bug fixing workflow
If you discover a bug in a gem your app uses, you can clone or edit the gem locally and point Bundler to it while testing the fix.
Real Codebase Usage
In real projects, developers commonly use local gems as a temporary development tool rather than a permanent production dependency.
Common patterns
Local override during development
A team may normally use a released gem version:
gem 'my_gem', '~> 2.1'
But while debugging locally, they temporarily switch to:
gem 'my_gem', path: '../my_gem'
Shared internal libraries
Large codebases often extract repeated logic into gems such as:
- authentication helpers
- API clients
- logging utilities
- billing logic
During active development, these are often linked by path.
Dependency validation
When Bundler loads a local gem, it still checks the gemspec dependencies. That helps keep the app and gem dependency graph consistent.
Guarding environment-specific setup
Some teams avoid committing local paths to shared branches because teammates may not have the same folders. Instead, they use local path gems only in personal development branches or with agreed directory structures.
Release workflow
A common workflow is:
- develop the gem locally
- test it in an app via
:path - publish a version
Common Mistakes
Wrong path
If the path is incorrect, Bundler cannot find the gem.
Broken example:
gem 'my_gem', path: './my_gem'
This is wrong if my_gem is actually a sibling directory rather than inside the app folder.
Fix:
gem 'my_gem', path: '../my_gem'
Gem name does not match gemspec
The gem name in the Gemfile must match the gem's gemspec name.
Broken example:
gem 'my-gem', path: '../my_gem'
If the gemspec defines the name as my_gem, Bundler may not resolve it correctly.
Missing gemspec
Bundler expects the local directory to contain a valid gemspec.
Broken situation:
- folder exists
- source files exist
- no
.gemspecfile exists
Fix:
Comparisons
| Approach | Example | Best for | Notes |
|---|---|---|---|
| RubyGems source | gem 'my_gem' | stable published dependencies | Downloads from configured gem source |
| Local path | gem 'my_gem', path: '../my_gem' | local development and testing | Uses a folder on your machine |
| Git source | gem 'my_gem', git: 'https://github.com/user/my_gem.git' | using unreleased remote code | Good when code is not local but not published |
:path vs :git
:pathuses code already on your machine:gitfetches code from a repository- is usually fastest for local development
Cheat Sheet
# Use a local gem
gem 'my_gem', path: '../my_gem'
# Use several gems from the same local base folder
path '../components' do
gem 'auth_gem'
gem 'ui_gem'
end
Rules
- the folder must contain a valid
.gemspec - the gem name must match the gemspec name
- run
bundle installafter editing theGemfile - prefer relative paths over absolute paths
- you do not move gems into
.bundle
When to use :path
- local gem development
- testing unpublished changes
- working on app and gem together
When not to use it permanently
- when teammates or deployment environments do not share the same filesystem layout
- when the gem should be consumed as a released version instead
Useful command
bundle install
FAQ
Can Bundler use a gem from a local folder?
Yes. Use the :path option in your Gemfile.
gem 'my_gem', path: '../my_gem'
Do I need to move the gem into .bundle?
No. You normally keep the gem where it already lives and point Bundler to that directory.
Does the local gem need a gemspec?
Yes. Bundler expects a valid .gemspec in the local gem directory.
Can I use an absolute path?
Yes, but relative paths are usually better because they are more portable across machines.
Is a local path gem good for production?
Usually it is best for development. For production or shared environments, published gems or Git sources are often easier to manage.
What is the difference between :path and :git?
:path uses a local folder on your machine. :git fetches the gem from a repository.
Will Bundler automatically detect changes in the local gem?
It uses the local source directly, so your app sees local code changes. In some cases you may need to rerun commands or restart your app process depending on the environment.
Mini Project
Description
Create a small Ruby app that uses a gem from a sibling local folder. This demonstrates how Bundler links local code during development without publishing the gem first.
Goal
Set up a Ruby project that loads and runs code from a local gem using path: in the Gemfile.
Requirements
- Create one folder for the app and one sibling folder for the gem.
- Add a valid
.gemspecfile to the local gem. - Reference the gem in the app's
Gemfileusingpath:. - Write a simple method in the gem and call it from the app.
- Run the app successfully through Bundler.
Keep learning
Related questions
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.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.