In a Bundler 4 Gemfile.lock, what do the GEM, PLATFORMS, DEPENDENCIES, CHECKSUMS and BUNDLED WITH sections each record?
answer
- sources first, then metadata sections
- GEM specs: exact versions, transitive too
- DEPENDENCIES: the Gemfile's own lines
- CHECKSUMS: sha256 per gem, default since 4.0
- BUNDLED WITH drives version autoswitch
basics
~20 sGEM 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 sA 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# 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 platformgo deeper
Recall that Gemfile.lock records exact versions for every gem, including ones you never declared, and that it is committed alongside the Gemfile.
Walk through each section: source blocks with specs, PLATFORMS, DEPENDENCIES with the ! marker, CHECKSUMS and BUNDLED WITH, and say which command changes each.
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.
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