RubyGems

ID

gem

Home page

https://rubygems.org

Version requirement

>= 2.5

Platforms

🅱️ BSD · 🐧 Linux · 🍎 macOS · ⨂ Unix · 🪟 Windows

Operations

installed · outdated · search · install · upgrade · upgrade_all · remove · sync · cleanup · doctor

purl types

pkg:gem · pkg:rubygems

CLI name

gem

Every call

gem <command> --quiet

Issues and PRs

📦 manager: gem

Source

meta_package_manager/managers/gem.py

The RubyGems package manager.

gem emits no machine-readable format, so installed, outdated and search listings are parsed from its text output. A gem can keep several versions installed side by side (molinillo (0.5.4, 0.4.5, 0.2.3)); mpm reports the highest as the installed version.

Note

All operations target the default gem scope (controlled by GEM_HOME). On system Ruby this means system-level gems, which may require elevated privileges for write operations: those carry dormant privileged markers, so mpm --sudo or a [mpm.managers.gem] sudo = true override escalates them, while nothing escalates by default. On recent macOS that default scope lives on the sealed, read-only system volume, so the gems Ruby bundles there surface as outdated yet cannot be upgraded in place, not even with sudo: point mpm at a writable, user-controlled Ruby earlier on your PATH instead. Per-scope targeting (system vs user gems) is tracked in #1725.

Tip

Installs require sudo on system ruby. I (@tresni) recommend doing something like:

$ sudo dseditgroup -o edit -a -t user wheel

And then do visudo to make it so the wheel group does not require a password. There is a line already there for it, you just need to uncomment it and save.

What mpm adds to gem

Through mpm, gem gains --extended search, to match against package descriptions.

Bigger still, mpm reaches across every manager at once: mpm installed and mpm outdated cover gem alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.

Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.

Your gem commands, in mpm

You already know gem: each operation maps one-to-one onto mpm, in an interface shared by every manager.

To…

With gem

With mpm

List what’s installed

gem list

mpm --gem installed

List outdated packages

gem outdated

mpm --gem outdated

Search for a package

gem search python --versions

mpm --gem search python

Install a package

gem install markdown

mpm install pkg:gem/markdown

Upgrade one package

gem update markdown

mpm --gem upgrade markdown

Upgrade everything

gem update

mpm --gem upgrade --all

Remove a package

gem uninstall left-pad

mpm remove pkg:gem/left-pad

Clear caches

gem cleanup

mpm --gem cleanup --cache

Run health checks

gem check

mpm --gem doctor

Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.

Operations

Operation

Supported

Notes

installed

outdated

orphans

search

extended search backfilled by mpm

install

upgrade

upgrade_all

remove

sync

cleanup

doctor

Selecting and configuring gem

Deselect gem for a single run with --no-gem, or persist the choice in your configuration:

[mpm]
gem = false

The arguments and environment variables listed in the box atop this page are forced on every gem call, so runs stay quiet, non-interactive and reproducible: the defaults you would set in CI anyway.

Keep it enabled but tune how mpm drives it with a per-manager override:

[mpm.managers.gem]
timeout = 900

mpm config-template gem prints every overridable attribute as a ready-to-paste block.

Recipes

A few jobs you would otherwise script around gem, one mpm command each:

  • Snapshot and clone a machine: mpm --gem dump gem.toml, then mpm restore gem.toml on the next one.

  • Export a compliance SBOM: mpm --gem sbom (CycloneDX by default, --spdx for SPDX).

  • Gate CI on health: mpm --gem doctor relays RubyGems’s own diagnosis and exits non-zero on trouble.

Privilege escalation

mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.

See privilege escalation for the full policy.

Cooldown

State of RubyGems’s release-age gating, from the cooldown support table:

  • Status: 🚧 Proposed (Bundler PR open)

  • Mechanism: --cooldown / BUNDLE_COOLDOWN / per-source cooldown:

  • Reference: ruby/rubygems#9576

A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:

  • Registry: RubyGems.org (pkg:gem)

  • Retraction: Unpublish: gem yank “permanently removes a gem you pushed to a server”, dropping it from the index

  • Publish date: ✅ created_at and built_at, plus a yanked boolean (API)

With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --allow-unsupported-managers opts back in.

Version probe

The version is extracted from the output of gem --version with:

r"(?P<version>\S+)"

Reference traces

Raw native outputs captured in the manager source: the reference mpm’s parsers were written against. If you know RubyGems well and a transcript below looks wrong, or a newer release changed its output format, report it.

$ gem list --quiet
bigdecimal (default: 1.4.1)
bundler (default: 1.17.2)
CFPropertyList (2.3.6)
cmath (default: 1.0.0)
csv (default: 3.0.9)
date (default: 2.0.0)
fileutils (1.4.1, default: 1.1.0)
io-console (0.5.6, default: 0.4.7)
ipaddr (default: 1.2.2)
molinillo (0.5.4, 0.4.5, 0.2.3)
nokogiri (1.5.6)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
sqlite3 (1.3.7)
test-unit (2.0.0.0)
$ gem outdated --quiet
did_you_mean (1.0.0 < 1.0.2)
io-console (0.4.5 < 0.4.6)
json (1.8.3 < 2.0.1)
minitest (5.8.3 < 5.9.0)
power_assert (0.2.6 < 0.3.0)
psych (2.0.17 < 2.1.0)

Feed any of these through mpm and the raw output becomes one uniform table, the same shape for every manager: filter it, project columns, or export it (mpm --gem installed --output json, or csv, toml, yaml), each package carrying a purl and a version comparable across managers.

Changelog

  • 7.4.1 (2026-07-28)

    • Document that on recent macOS the system Ruby’s bundled gems surface as outdated yet cannot be upgraded in place, and point to running mpm against a writable Ruby earlier on PATH as the fix.

  • 7.4.0 (2026-07-25)

    • The write operations carry dormant privileged markers like pip and npm: --sudo or a per-manager sudo = true override escalates installs into a system Perl or Ruby. Nothing escalates by default.

  • 6.4.0 (2026-04-27)

    • Add sync operation.

  • 6.3.0 (2026-04-09)

    • Remove --user-install flag from install, upgrade, and update commands so all operations target the same gem scope as list and outdated. Closes #389.

  • 6.0.0 (2025-12-08)

    • Remove hard-coded gem CLI search path.

  • 5.8.0 (2022-10-05)

    • Implement remove operation.

  • 3.1.0 (2020-04-02)

    • Ignore default: prefix on package version parsing.

    • Bump minimal requirement to 2.5.0.

  • 2.9.0 (2020-03-18)

    • Force Ruby gem to install packages to user-install by default. Refs #58.

  • 2.5.0 (2017-03-01)

    • Allow use of apm, gem and npm managers on Linux.

  • 2.4.0 (2017-01-28)

    • Fix listing of gems installed in several versions at once (like molinillo (0.5.4, 0.4.5, 0.2.3)), reporting the latest of them.

  • 2.3.0 (2017-01-15)

    • Fix the exception raised when gem returns no output. Closes #29.

  • 1.4.0 (2016-07-10)

    • Support system or Homebrew Ruby Gems (with proper sudo setup).

  • 1.2.0 (2016-07-08)

    • Add support for both pip2 and pip3, Node’s npm, Atom’s apm, Ruby’s gem.