Question

Update One Gem with Bundler in Ruby and Rails

rubyrubygemsbundler

Question

In a Rails application, Bundler manages dependencies. A gem from a Git repository is declared in the Gemfile like this:

gem "gem-name", git: "path/to/my/gem.git"

Running bundle update updates this gem but also updates other gems listed in the Gemfile. What command updates only this specific gem?

Short Answer

You will learn how Bundler uses Gemfile.lock to keep dependency versions stable and how to request an update for one named gem with bundle update gem-name. You will also see what “only one gem” means in practice: Bundler may update that gem's required dependencies when necessary to produce a valid dependency set.

Concept

Bundler manages a Ruby application's dependencies as a set of compatible versions.

  • The Gemfile states what your application is allowed to use.
  • The Gemfile.lock records the exact versions and Git revisions currently selected.
  • bundle install normally installs the versions already recorded in the lockfile.
  • bundle update asks Bundler to resolve newer versions and write a new lockfile.

To update one gem, pass its gem name to bundle update:

bundle update gem-name

For a Git-based dependency, Bundler fetches the configured repository and can move the lockfile from its current commit revision to a newer revision on the configured branch or ref.

The name after bundle update must be the gem's name—the name declared by the gem's .gemspec—not necessarily the Git repository name.

Although this is a targeted update, Bundler cannot promise that exactly one line of the lockfile will change. If the new version of gem-name needs a newer compatible dependency, Bundler may update that dependency too. This preserves a working, compatible bundle.

Mental Model

Think of the lockfile as a saved shopping list with exact product versions.

  • bundle install buys exactly what is on the saved list.
  • bundle update throws away the saved choices and rebuilds much of the list with newer products.
  • bundle update gem-name says: “Replace this one product with its latest compatible version, while keeping the rest of the list as stable as possible.”

If the replacement needs a different compatible accessory, Bundler is allowed to replace that accessory as well. It must make sure the whole cart still fits together.

Take Quiz

Syntax and Examples

The targeted-update syntax is:

bundle update GEM_NAME

For example:

bundle update gem-name

A modern Git dependency declaration looks like this:

# Gemfile
gem "gem-name", git: "https://example.com/team/gem-name.git"

After running the update, inspect the changes:

git diff Gemfile.lock

For a Git gem, the lockfile contains a GIT section with a revision. A successful targeted update may change that revision:

GIT
  remote: https://example.com/team/gem-name.git
  revision: a_new_commit_sha
  specs:
    gem-name (1.2.0)

If you want to restrict the dependency changes even more, use Bundler's conservative mode:

bundle update gem-name --conservative

This tells Bundler to prefer keeping indirect dependencies at their currently locked versions when possible. It still cannot keep a dependency unchanged if the requested gem version requires a change.

Step by Step Execution

Suppose the project currently has this dependency:

# Gemfile
gem "reporting_tools", git: "https://github.com/example/reporting_tools.git"

Its lockfile currently records commit 111aaa:

GIT
  remote: https://github.com/example/reporting_tools.git
  revision: 111aaa
  specs:
    reporting_tools (2.0.0)

Run:

bundle update reporting_tools

Bundler then works through these steps:

  1. It reads Gemfile and sees that reporting_tools comes from Git.
  2. It reads Gemfile.lock and sees the currently locked revision, 111aaa.
  3. It fetches information from the configured Git remote.
  4. It resolves a newer compatible revision of reporting_tools.
  5. It checks whether that revision's dependencies are compatible with the rest of the bundle.
  6. It writes the selected revision, and any necessary dependency changes, to Gemfile.lock.
  7. It installs the resolved gems locally.

The resulting lockfile might contain:

GIT
  remote: https://github.com/example/reporting_tools.git
  revision: 222bbb
  specs:
    reporting_tools (2.1.0)

Finally, run the relevant test suite before committing the lockfile change.

Real World Use Cases

Targeted gem updates are useful when you want a small, reviewable dependency change.

  • Bug fix from an internal Git gem: A teammate pushes a fix to a shared library repository, and your Rails app needs that newer commit.
  • Security maintenance: Update a vulnerable direct dependency without intentionally refreshing the entire dependency tree.
  • Incremental upgrades: Update one integration gem, run its tests, and deal with compatibility issues before updating others.
  • Production incident response: Pull in a specific library fix while minimizing unrelated changes before deploying.
  • Dependency review: Create a focused pull request where reviewers can inspect the changed lockfile entries and test results.
Take Quiz

Real Codebase Usage

In real Ruby projects, developers usually make dependency updates deliberately and commit the resulting lockfile.

Update a direct dependency

bundle update nokogiri

Then review the lockfile:

git diff -- Gemfile.lock

Keep updates narrow

When a project has a large dependency graph, conservative mode can reduce unnecessary indirect updates:

bundle update nokogiri --conservative

Pin a Git gem to a known commit

A moving branch is convenient during development but less reproducible. For a deliberate, repeatable deployment, pin a Git dependency to a commit:

gem "reporting_tools",
    git: "https://github.com/example/reporting_tools.git",
    ref: "222bbb333ccc444ddd"

After changing the Gemfile, run:

bundle install

Typical team workflow

  1. Update the intended gem.
  2. Review Gemfile.lock for unexpected changes.
  3. Run tests, linting, and any affected integration checks.
  4. Commit both Gemfile changes, if any, and Gemfile.lock.

Applications generally commit Gemfile.lock so local development, CI, and production use the same resolved dependency versions.

Common Mistakes

Running a full update unintentionally

bundle update

This may update many gems because no target was specified.

Use this instead:

bundle update gem-name

Expecting bundle install to fetch the newest Git commit

bundle install

When Gemfile.lock exists and the Gemfile has not changed, this normally installs the locked Git revision. It does not mean “get the latest commit.” Use a targeted update to refresh the Git revision.

Using the repository name instead of the gem name

The repository could be named reporting-tools-ruby, while its gemspec contains:

Gem::Specification.new do |spec|
  spec.name = "reporting_tools"
end

The correct command is:

bundle update reporting_tools

Assuming no indirect dependencies can change

A targeted update is narrower than a full update, but a new gem version may require a compatible newer version of another gem. Review Gemfile.lock rather than assuming only one entry changed.

Ignoring the lockfile

Do not update locally and forget to commit Gemfile.lock. Other developers and CI may otherwise continue using the old version or resolve a different set of dependencies.

Using an unstable Git branch without awareness

A declaration that follows a branch can change whenever new commits are pushed:

gem "gem-name", git: "https://example.com/gem-name.git", branch: "main"

This is acceptable for some workflows, but pinning a ref is safer when reproducibility matters.

Comparisons

Command or approachWhat it doesBest use
bundle installInstalls versions and Git revisions already locked, unless the Gemfile changed.Setting up a project or reproducing the current bundle.
bundle updateRe-resolves and may update the whole dependency set.Planned broad dependency maintenance.
bundle update gem-nameUpdates the named gem and any dependencies that must change for compatibility.A focused gem update.
bundle update gem-name --conservativeAttempts to keep indirect dependencies locked where possible.Minimizing lockfile movement in a large project.
Git dependency with branch:Follows the current commit on a branch when updated.Active development against a branch.
Git dependency with ref:Uses one specific Git commit.Reproducible builds and controlled releases.
Take Quiz

Cheat Sheet

# Update one gem
bundle update gem-name

# Update one gem while preferring locked indirect dependencies
bundle update gem-name --conservative

# Install exactly what the lockfile currently specifies
bundle install

# Inspect dependency-lockfile changes
git diff -- Gemfile.lock
# Git dependency
 gem "gem-name", git: "https://example.com/org/gem-name.git"

# Follow a particular branch
 gem "gem-name", git: "https://example.com/org/gem-name.git", branch: "main"

# Pin one exact commit for repeatability
 gem "gem-name", git: "https://example.com/org/gem-name.git", ref: "commit-sha"
  • Use the gemspec's gem name in bundle update GEM_NAME.
  • Commit Gemfile.lock for applications.
  • A targeted update can still update required indirect dependencies.
  • Test after changing dependencies.

FAQ

How do I update only one gem with Bundler?

Run:

bundle update gem-name

Replace gem-name with the dependency's actual gem name.

Does bundle update gem-name update every gem?

It targets the named gem. However, Bundler may also update dependencies required to make the selected version compatible with the bundle.

How do I update a Git-based gem to the latest commit?

Run bundle update with that gem's name. Bundler fetches the configured repository and updates the revision stored in Gemfile.lock when a newer compatible revision is available.

Why does bundle install not update my Git gem?

bundle install normally respects the revision already recorded in Gemfile.lock. Use bundle update gem-name to request a newer revision.

What name should I pass to bundle update?

Use the name from the gem's .gemspec, such as reporting_tools. It may differ from the repository or folder name.

Can I prevent all indirect dependency updates?

Not always. If the new version requires another dependency to change, Bundler must change it. --conservative can reduce unnecessary indirect updates:

bundle update gem-name --conservative

Should Gemfile.lock be committed in a Rails app?

Yes. Committing it makes development, CI, and deployments use the same resolved dependency versions and Git revisions.

Take Quiz

Mini Project

Description

Create a small dependency-maintenance checklist for a Rails application that uses both a RubyGems dependency and an internal Git-hosted gem. The exercise demonstrates a focused Bundler update, lockfile review, and a reproducible Git dependency pin.

Goal

Update only the internal Git gem, verify the lockfile change, and pin the selected revision for a repeatable build.

Requirements

Use a Gemfile containing one normal gem and one Git-hosted gem. Run a targeted update for the Git-hosted gem only. Review the Gemfile.lock diff before accepting the update. Pin the Git dependency to the revision selected by Bundler. Run bundle install after changing the pin.

Take Quiz

Keep learning

Related questions

View more