ZetCode

Ruby Bundler and Gemfile

last modified October 18, 2026

Bundler is the dependency manager for Ruby. It reads a Gemfile that declares the gems an application needs, resolves a consistent set of versions, records the result in Gemfile.lock, and makes sure only those versions are loaded at runtime. This guide covers the Gemfile syntax, version constraints, the lockfile, the common bundle commands, groups, and the gemspec directive. The examples were run with Bundler 2.2.22 using a local path gem and an already installed rake, so they work offline.

Writing a Gemfile

A Gemfile declares a gem source and a list of gem dependencies. The pessimistic operator ~> allows updates within a range, while >= sets a lower bound only. The path: option points at a gem stored in the project tree.

Gemfile
source "https://rubygems.org"

gem "rake", "~> 13.0"
gem "greeter", path: "greeter"

group :test do
  gem "minitest"
end

The source line selects the gem server. "~> 13.0" means versions >= 13.0 and < 14.0. The path: gem is loaded from the local greeter directory. The group :test block marks minitest as needed only for testing.

Installing Gems

bundle install resolves the Gemfile and writes the exact versions to Gemfile.lock. The --local flag uses only gems that are already installed, so no network is needed. Run it from the project directory that contains the Gemfile.

$ bundle install --local
Running `bundle install --local` with bundler 2.2.22
Found no changes, using resolution from the lockfile
Using rake 13.0.6
0:  rake (13.0.6) from /usr/share/rubygems-integration/all/specifications/rake-13.0.6.gemspec
Using bundler 2.2.22
0:  bundler (2.2.22) from /usr/lib/ruby/gems/3.0.0/specifications/default/bundler-2.2.22.gemspec
Using greeter 0.1.0 from source at `greeter`
Following files may not be writable, so sudo is needed:
  /usr/local/bin
  /var/lib/gems/3.0.0
0:  greeter (0.1.0) from /tmp/kilo/bundler/greeter/greeter.gemspec
Using minitest 5.14.2
0:  minitest (5.14.2) from /usr/lib/ruby/gems/3.0.0/specifications/minitest-5.14.2.gemspec
Bundle complete! 3 Gemfile dependencies, 4 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

The Gemfile.lock File

Gemfile.lock records every resolved gem with its exact version, including transitive dependencies. Commit it for applications so every machine uses the same versions. Do not edit it by hand; let Bundler regenerate it with bundle install or bundle update.

Gemfile.lock
PATH
  remote: greeter
  specs:
    greeter (0.1.0)

GEM
  remote: https://rubygems.org/
  specs:
    minitest (5.14.2)
    rake (13.0.6)

PLATFORMS
  x86_64-linux

DEPENDENCIES
  greeter!
  minitest
  rake (~> 13.0)

BUNDLED WITH
   2.2.22

The GEM section lists the exact versions Bundler resolved. The DEPENDENCIES section mirrors the Gemfile: rake (~> 13.0) keeps the constraint, while the locked version is 13.0.6. greeter! marks a path gem.

Running Code with bundle exec and bundler/setup

bundle exec runs a command with the bundled gem versions active. Calling require 'bundler/setup' at the top of a script does the same for that script: it restricts require to gems listed in the Gemfile.

app.rb
require 'bundler/setup'
require 'greeter'

puts Greeter.hello("Bundler")

The bundler/setup line activates the bundle before any other require. Because greeter is a path gem in the Gemfile, it loads from the local directory. Running the script with bundle exec gives the same environment from the command line.

$ bundle exec ruby app.rb
Hello, Bundler!

Listing and Showing Gems

bundle list prints every gem in the bundle, and bundle show prints the install path of one gem. Both read the lockfile, so they report resolved versions rather than constraints.

Shell session
$ bundle list
$ bundle show rake
$ bundle exec rake --version

The first command lists all bundled gems, the second shows where rake is installed on disk, and the third runs the bundled rake executable. bundle info rake gives more detail on a single gem.

$ bundle list
Running `bundle list` with bundler 2.2.22
Found no changes, using resolution from the lockfile
Gems included by the bundle:
  * greeter (0.1.0)
  * minitest (5.14.2)
  * rake (13.0.6)
Use `bundle info` to print more detailed information about a gem
$ bundle show rake
Found no changes, using resolution from the lockfile
/usr/share/rubygems-integration/all/gems/rake-13.0.6
$ bundle exec rake --version
rake, version 13.0.6

Installing Without a Group

Groups keep test-only gems out of production installs. Gems inside a group block are skipped when that group is excluded with --without. Excluded gems are not installed and are not loaded by bundler/setup. Here minitest is in the :test group, so excluding it leaves rake in place.

Shell session
$ bundle install --local --without test
$ bundle list

The install skips the test group, and the list then shows only the gems outside that group. Bundler prints a deprecation notice because the --without flag is remembered between runs in older versions; the modern replacement is bundle config set --local without 'test'.

$ bundle install --local --without test
Running `bundle install --local --without "test"` with bundler 2.2.22
[DEPRECATED] The `--without` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set --local without 'test'`, and stop using this flag
Found no changes, using resolution from the lockfile
Using rake 13.0.6
0:  rake (13.0.6) from /usr/share/rubygems-integration/all/specifications/rake-13.0.6.gemspec
Using bundler 2.2.22
0:  bundler (2.2.22) from /usr/lib/ruby/gems/3.0.0/specifications/default/bundler-2.2.22.gemspec
Using greeter 0.1.0 from source at `greeter`
Following files may not be writable, so sudo is needed:
  /usr/local/bin
  /var/lib/gems/3.0.0
0:  greeter (0.1.0) from /tmp/kilo/bundler/greeter/greeter.gemspec
Bundle complete! 3 Gemfile dependencies, 3 gems now installed.
Gems in the group 'test' were not installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
$ bundle list
Running `bundle list` with bundler 2.2.22
Found no changes, using resolution from the lockfile
Gems included by the bundle:
  * greeter (0.1.0)
  * rake (13.0.6)
Use `bundle info` to print more detailed information about a gem

Using gemspec in a Gemfile

The gemspec directive pulls in a library's own gemspec file. The gem's runtime dependencies come from the gemspec, and development dependencies can be added in the Gemfile. It is most useful when you are developing a gem itself.

Gemfile
source "https://rubygems.org"

gemspec

With this Gemfile in the directory containing mylib.gemspec, the gem mylib is added to the bundle from that gemspec, loaded from the current directory.

$ bundle install --local
Running `bundle install --local` with bundler 2.2.22
Found no changes, using resolution from the lockfile
Using bundler 2.2.22
0:  bundler (2.2.22) from /usr/lib/ruby/gems/3.0.0/specifications/default/bundler-2.2.22.gemspec
Using mylib 0.1.0 from source at `.`
Following files may not be writable, so sudo is needed:
  /usr/local/bin
  /var/lib/gems/3.0.0
0:  mylib (0.1.0) from /tmp/kilo/bundler/mylib/mylib.gemspec
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
$ bundle list
Running `bundle list` with bundler 2.2.22
Found no changes, using resolution from the lockfile
Gems included by the bundle:
  * mylib (0.1.0)
Use `bundle info` to print more detailed information about a gem

List all Ruby tutorials.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.