Question

How to Use a Local Gem in a Gemfile with Bundler (Ruby)

rubyruby-on-railsruby-on-rails-3rubygemsbundler

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.

Take Quiz

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:

path '../components' do
  gem 'auth_gem'
  gem 'ui_gem'
end

This is useful when several gems live under one directory.

Important note

The gem folder should contain a valid .gemspec file. Bundler relies on that metadata to load the gem correctly.

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

  1. Bundler reads the Gemfile.
  2. It sees that my_gem has a :path option.
  3. Instead of checking RubyGems, Bundler looks in ../my_gem.
  4. It reads the gemspec in that folder.
  5. It resolves the gem's dependencies from the gemspec.
  6. It records the local path source in Gemfile.lock.
  7. Your Ruby app can now require that gem like a normal dependency.

Small example

my_gem/lib/my_gem.rb

module MyGem
  def self.greet
    'Hello from local gem'
  end
end

In your app:

require 'my_gem'

puts MyGem.greet

Output:

Hello from local gem

Because Bundler linked the gem from your local folder, your app uses your local code directly.

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.

Take Quiz

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:

  1. develop the gem locally
  2. test it in an app via :path
  3. publish a version
  4. change the Gemfile back to the published 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 .gemspec file exists

Fix:

  • create a proper gemspec for the gem

Assuming .bundle is where local gems go

This is a common misunderstanding. .bundle stores Bundler configuration, not your gem source code workflow.

Committing machine-specific paths

An absolute path like this can break on another developer's machine:

gem 'my_gem', path: '/Users/alex/projects/my_gem'

Prefer relative paths when possible:

gem 'my_gem', path: '../my_gem'

Forgetting to run Bundler again

After changing the Gemfile, run:

bundle install

This updates dependency resolution and the lockfile.

Comparisons

ApproachExampleBest forNotes
RubyGems sourcegem 'my_gem'stable published dependenciesDownloads from configured gem source
Local pathgem 'my_gem', path: '../my_gem'local development and testingUses a folder on your machine
Git sourcegem 'my_gem', git: 'https://github.com/user/my_gem.git'using unreleased remote codeGood when code is not local but not published

:path vs :git

  • :path uses code already on your machine
  • :git fetches code from a repository
  • :path is usually fastest for local development
  • :git is easier to share across machines if everyone has repository access

Relative path vs absolute path

Path typeExampleProsCons
Relative../my_gemportable within a known folder structuredepends on project layout
Absolute/Users/name/projects/my_gemexplicitusually not team-friendly

Path gem vs copied source code

Copying a gem into another directory manually creates duplication. Using :path keeps one source of truth and is much easier to maintain.

Take Quiz

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 install after editing the Gemfile
  • 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.

Take Quiz

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

  1. Create one folder for the app and one sibling folder for the gem.
  2. Add a valid .gemspec file to the local gem.
  3. Reference the gem in the app's Gemfile using path:.
  4. Write a simple method in the gem and call it from the app.
  5. Run the app successfully through Bundler.
Take Quiz

Keep learning

Related questions

View more