skip to content

In a Bundler 4 Gemfile.lock, what do the GEM, PLATFORMS, DEPENDENCIES, CHECKSUMS and BUNDLED WITH sections each record?

level: middleimportance: should knowfreq 42%

answer

  1. sources first, then metadata sections
  2. GEM specs: exact versions, transitive too
  3. DEPENDENCIES: the Gemfile's own lines
  4. CHECKSUMS: sha256 per gem, default since 4.0
  5. BUNDLED WITH drives version autoswitch

basics

~20 s

GEM lists every resolved gem with its exact version; PLATFORMS lists the platforms the resolution covers; DEPENDENCIES repeats the Gemfile's direct requirements; CHECKSUMS stores a sha256 per gem (default on in Bundler 4); BUNDLED WITH names the Bundler version that wrote it.

solid answer

~40 s

A Gemfile.lock starts with one block per source - `GEM` for a gem server, plus `GIT` or `PATH` for those sources - whose `specs:` list every resolved gem with its exact version, transitive ones included, each followed by its own dependency requirements. `PLATFORMS` lists the platforms the resolution was done for, such as `ruby`, `arm64-darwin` or `x86_64-linux`. `DEPENDENCIES` repeats only the gems the Gemfile declares, with their constraints; a trailing `!` marks one that comes from a non-default source. `CHECKSUMS` records a `sha256=` digest per gem so a changed package is detected; Bundler 4 turns `lockfile_checksums` on by default for new lockfiles. `RUBY VERSION` appears when the Gemfile has a `ruby` line, and `BUNDLED WITH` records the Bundler version, which Bundler switches to by default.

code

bash · 8 lines
bash
# add a CHECKSUMS section to an older lockfile
bundle lock --add-checksums

# move the BUNDLED WITH line to a specific Bundler
bundle update --bundler=4.0.21

# show the platforms your app's gems support
bundle platform

go deeper

for a junior

Recall that Gemfile.lock records exact versions for every gem, including ones you never declared, and that it is committed alongside the Gemfile.

for a middle

Walk through each section: source blocks with specs, PLATFORMS, DEPENDENCIES with the ! marker, CHECKSUMS and BUNDLED WITH, and say which command changes each.

for a senior

Read a lockfile diff in review: tell a transitive bump from a Gemfile change, spot an unintended platform or Bundler change, and add checksums to legacy lockfiles.

for a principal

Weigh how strictly the team treats lockfile hunks in review, such as requiring an explanation for BUNDLED WITH or PLATFORMS changes versus accepting routine transitive churn.

## Why the layout matters Gemfile.lock is plain text that Bundler writes after resolving a Gemfile and reads on every later `bundle install`. Interviewers ask about its sections because reading a lockfile diff in review is a daily task: you should know whether a changed line is a new transitive gem, a new platform, or a different Bundler. Bundler writes the sections in a fixed order: the **source blocks**, then `PLATFORMS`, `DEPENDENCIES`, `CHECKSUMS`, `RUBY VERSION` and `BUNDLED WITH`. ``` GEM remote: https://rubygems.org/ specs: mustermann (3.0.4) ruby2_keywords (~> 0.0.1) rack (3.2.7) ruby2_keywords (0.0.5) PLATFORMS arm64-darwin x86_64-linux DEPENDENCIES mustermann (~> 3.0) rack (~> 3.2) CHECKSUMS mustermann (3.0.4) sha256=<hex digest> rack (3.2.7) sha256=<hex digest> ruby2_keywords (0.0.5) sha256=<hex digest> BUNDLED WITH 4.0.21 ``` ## Source blocks: GEM, GIT, PATH Each source in the Gemfile becomes one block: - **`GEM`** - a gem server, with its `remote:` URL and a `specs:` list. - **`GIT`** - a git source, with `remote:`, the locked `revision:` and any `branch:`/`ref:`/`tag:`. - **`PATH`** - a local directory source. Under `specs:` every **resolved** gem appears with its exact version: `rack (3.2.7)`. Transitive gems are listed too - `ruby2_keywords` above is there only because `mustermann` needs it. The indented lines under a spec are that gem's **own** dependency requirements, copied from its gemspec, which is how you trace why a transitive gem is present. A gem built for a specific platform carries it in the version, such as `nokogiri (<version>-x86_64-linux)`. ## PLATFORMS and DEPENDENCIES **`PLATFORMS`** lists the platforms the resolution covers. `ruby` means the pure-Ruby or compile-from-source variant; entries such as `x86_64-linux` or `arm64-darwin` let Bundler pick precompiled native gems for those systems. `bundle lock --add-platform` and `--remove-platform` edit this list. **`DEPENDENCIES`** is the Gemfile's own list: only direct gems, with the constraint written in the Gemfile, sorted. A trailing `!` (as in `warbler!`) marks a gem pinned to a non-default source such as a `GIT` or `PATH` block. Bundler compares this section with the current Gemfile to decide whether the Gemfile changed and a re-resolve is needed. ## CHECKSUMS **`CHECKSUMS`** records one line per gem: name, version and a digest such as `sha256=...`. When Bundler later installs a `.gem`, a digest that does not match raises `Bundler::ChecksumMismatchError` instead of installing the altered file. - The section exists since Bundler 2.5. - In **Bundler 4.0** the `lockfile_checksums` setting defaults to `true`, so every **new** lockfile gets it. - An **existing** lockfile without the section stays without it until you run `bundle lock --add-checksums`. - Since 4.0.11 Bundler also records its own checksum, but only when its `.gem` file is cached. ## RUBY VERSION and BUNDLED WITH **`RUBY VERSION`** appears only when the Gemfile has a `ruby` directive; Bundler 4 no longer writes the patchlevel there. `bundle update --ruby` moves it. **`BUNDLED WITH`** names the Bundler version that wrote the file. It is not decoration: with the default `version` setting of `lockfile`, `bundle install` running under a different Bundler installs the locked version and re-executes itself under it, unless `BUNDLER_VERSION` is set in the environment. To move the line on purpose, run `bundle update --bundler` (latest release) or `bundle update --bundler=4.0.21`. ## Which command changes which section Each section has a command that is expected to change it, which makes an unexpected hunk easy to question: 1. `bundle install` after a Gemfile edit - `DEPENDENCIES` plus the `specs:` and `CHECKSUMS` lines of the gems it had to resolve. 2. `bundle update <gem>` or `bundle update --all` - `specs:` versions and their `CHECKSUMS` lines. 3. `bundle lock --add-platform` or `--remove-platform` - `PLATFORMS`, plus platform-tagged `specs:` entries. 4. `bundle lock --add-checksums` - adds the `CHECKSUMS` section. 5. `bundle update --bundler` - `BUNDLED WITH`; `bundle update --ruby` - `RUBY VERSION`. ## Reading a lockfile diff | Changed section | Usually means | |---|---| | `specs:` version bump | a gem moved; check whether it was direct or transitive | | new `specs:` entry, no DEPENDENCIES change | a new transitive gem arrived with an update | | `DEPENDENCIES` | the Gemfile changed | | `PLATFORMS` | someone installed on a new platform or ran `--add-platform` | | `BUNDLED WITH` | someone ran a newer Bundler with `bundle update --bundler` | A reviewer who can map each hunk to one of these rows can tell an intended bump from an accidental resolution change.

  • Your Bundler 4 project has an old Gemfile.lock with no CHECKSUMS section. Does setting `lockfile_checksums` to true add one?
    No. The setting controls what Bundler writes into new lockfiles; an existing lockfile keeps its current shape. Run `bundle lock --add-checksums` once, review the diff and commit it; later installs then verify every gem against the recorded digests.
  • Why does running `bundle install` with Bundler 4 on a lockfile that says `BUNDLED WITH 2.6.9` sometimes print that it is installing Bundler 2.6.9?
    The default `version` setting is `lockfile`, so Bundler switches to the version the lockfile names: it installs that release and restarts itself under it. Setting `BUNDLER_VERSION` in the environment disables the switch; `bundle update --bundler` rewrites the line when the team is ready to move.

saying these in an interview costs you the question

  • DEPENDENCIES lists every installed gem, transitive ones included
  • BUNDLED WITH is informational and Bundler ignores it
  • CHECKSUMS appears only after running bundle lock --add-checksums
  • PLATFORMS lists the Ruby versions the app supports
  • The GEM specs block stores the Gemfile's version constraints