skip to content

Package Managers

Each ecosystem's own tool for reading a manifest, writing a lockfile and publishing to a registry, from npm and pip to Cargo and Bundler. Interviewers ask about the one your stack ships with.

on this pageshow

explore

questions

64 · 6 sections

With Bundler, why can a bare `rake test` load different gem versions than `bundle exec rake test`, and what does `bundle exec` change?

level: juniorimportance: must knowfreq 76%
basics
~20 s

A bare rake starts through RubyGems, which activates the newest installed rake, not the one Gemfile.lock pins. bundle exec runs Bundler.setup first, so the command sees only the locked versions and only the bundle's gems.

open as a page

In a Gemfile, what versions does `gem "rack", "~> 3.1"` accept, and how do `"~> 3.1.4"`, `">= 3.1"` and a bare `"3.1.4"` differ?

level: juniorimportance: must knowfreq 72%
basics
~20 s

In a Gemfile, ~> 3.1 is the pessimistic operator: at least 3.1 and below 4.0. ~> 3.1.4 allows 3.1.4 up to below 3.2, >= 3.1 has no upper bound at all, and a bare "3.1.4" means exactly = 3.1.4.

open as a page

With Bundler, what is the difference between `bundle install` and `bundle update` when a committed Gemfile.lock already exists?

level: juniorimportance: must knowfreq 74%
basics
~20 s

bundle install installs exactly the versions Gemfile.lock records and re-resolves only gems whose Gemfile entry changed. bundle update deliberately unlocks the named gems, or every gem with --all, and moves them to the newest versions the Gemfile allows.

open as a page

In Ruby with Bundler, what is the difference between `require "bundler/setup"` and `Bundler.require`, and how do group arguments change each?

level: middleimportance: must knowfreq 55%
basics
~20 s

require "bundler/setup" calls Bundler.setup, which puts the locked gems of all installed groups on the load path but loads none. Bundler.require runs setup and then requires every gem of the named groups, :default when called without arguments.

open as a page

In a Gemfile, what does putting gems inside `group :test do ... end` declare, and what does `require: false` on a gem change?

level: middleimportance: must knowfreq 58%
basics
~20 s

A group labels gems (ungrouped ones are in :default) so installs and Bundler.setup can include or skip them, yet every group still resolves into one Gemfile.lock. require: false keeps the gem installed and loadable but stops Bundler.require from requiring it automatically.

open as a page

In RubyGems 4, what do gem install, gem list, gem update and gem uninstall do, and does gem update remove the older version?

level: juniorimportance: must knowfreq 62%
basics
~20 s

gem install puts a gem and its runtime dependencies into GEM_HOME, gem list shows installed versions, gem update adds the newest version beside the old one, and gem uninstall removes a version. Only gem cleanup or uninstall deletes old versions.

open as a page

In RubyGems, what is a .gemspec file, which fields must it set, and what does gem build produce from it?

level: juniorimportance: must knowfreq 52%
basics
~10 s

A .gemspec is Ruby code that builds a Gem::Specification: name, version, summary, authors, files, require_paths and dependencies. gem build validates it and packages the listed files into name-version.gem, the file gem push uploads.

open as a page

In RubyGems, what is the difference between GEM_HOME and GEM_PATH, and where does gem install --user-install put gems?

level: middleimportance: must knowfreq 45%
basics
~10 s

GEM_HOME is the single directory gem install writes into; GEM_PATH is the list of directories RubyGems searches for installed gems, and GEM_HOME is always part of it. --user-install writes to Gem.user_dir, such as ~/.gem/ruby/4.0.0.

open as a page

In a RubyGems gemspec, what is the difference between add_dependency and add_development_dependency, and what goes wrong if you mix them up?

level: middleimportance: must knowfreq 55%
basics
~20 s

add_dependency declares a runtime dependency, installed and activated with your gem. add_development_dependency declares a tool needed only to work on the gem; gem install skips it unless --development is given, and it is never activated.

open as a page

When you publish version 1.0 of a gem with gem push, how do RubyGems API keys, MFA and --otp work, and which gemspec metadata hardens the release?

level: seniorimportance: must knowfreq 42%
basics
~20 s

gem push uploads a built .gem using an API key from gem signin or GEM_HOST_API_KEY. With MFA enabled, the server demands a one-time code passed via --otp or GEM_HOST_OTP_CODE. Metadata rubygems_mfa_required and allowed_push_host harden pushes.

open as a page

With RVM, what do `rvm install 4.0.7`, `rvm use 4.0.7` and `rvm use 4.0.7 --default` each do, and which one survives a new terminal?

level: juniorimportance: should knowfreq 32%
basics
~20 s

rvm install downloads a prebuilt Ruby or compiles one into ~/.rvm/rubies; rvm use switches only the current shell by rewriting PATH and the gem variables; adding --default also records it as the default alias that every new shell loads.

open as a page

Why did many Ruby teams move from RVM to rbenv, and what exactly changes for a project when they do?

level: middleimportance: should knowfreq 30%
basics
~20 s

RVM hooks cd, sources shell code into every session, manages gemsets and system packages, and last tagged 1.29.12 in 2021; rbenv just selects a Ruby and leaves gems to Bundler. Migrating keeps .ruby-version and drops .rvmrc, .ruby-gemset and RVM.

open as a page

On an inherited server set up with RVM gemsets, a cron job running `cd /srv/billing && bundle exec rake invoices:send` uses the wrong Ruby, though it works over SSH; why, and how do you fix it?

level: seniorimportance: should knowfreq 20%
basics
~20 s

RVM's selection is environment state set by a shell function your SSH login shell sources; cron's minimal shell never loads it, so no cd hook and no gemset. Use RVM wrappers, rvm in DIR do, or rvm cron setup.

open as a page

In RVM, what is a gemset, how do `rvm use 4.0.7@billing --create` and the `@global` gemset work together, and where do new gems go?

level: middleimportance: nice to knowfreq 22%
basics
~20 s

A gemset is a named gem directory attached to one installed Ruby. rvm use 4.0.7@billing --create creates and selects ~/.rvm/gems/ruby-4.0.7@billing; new gems install there, while gems in that Ruby's @global gemset stay visible to it.

open as a page

When you `cd` into a project, how does RVM choose the Ruby and gemset, and why must a `.rvmrc` be trusted first?

level: middleimportance: nice to knowfreq 14%
basics
~20 s

RVM's cd hook walks up from the new directory and loads the first project file it finds, with .rvmrc checked before .ruby-version. A .rvmrc is shell code sourced into your shell, so RVM asks before running it; .ruby-version is plain data.

open as a page

With rbenv, how do you install a new Ruby version and pin it for one project, and what does each command write to disk?

level: juniorimportance: must knowfreq 70%
basics
~10 s

Run rbenv install 4.0.7 (supplied by the ruby-build plugin) to build Ruby into ~/.rbenv/versions/4.0.7, then rbenv local 4.0.7 in the project to write .ruby-version; rbenv global writes the machine default to ~/.rbenv/version.

open as a page

How do rbenv shims route a ruby or bundle call to the right Ruby version, and when must you run rbenv rehash?

level: middleimportance: must knowfreq 55%
basics
~10 s

rbenv puts ~/.rbenv/shims first on PATH; each shim is a small script that runs rbenv exec, which resolves the selected version and execs that version's executable. rbenv rehash regenerates shims when new executables appear.

open as a page

In what order does rbenv decide which Ruby version is active, and how do rbenv shell, local and global map onto that order?

level: middleimportance: should knowfreq 50%
basics
~20 s

rbenv takes RBENV_VERSION first (set by rbenv shell), then the nearest .ruby-version found walking up from the current directory (written by rbenv local), then ~/.rbenv/version (written by rbenv global), and otherwise uses the system Ruby.

open as a page

Why is rbenv called the lighter alternative to RVM, and how do you isolate gems per project when rbenv has no gemsets?

level: middleimportance: should knowfreq 40%
basics
~20 s

rbenv only prepends a shims directory to PATH and resolves the version on each command, without wrapping cd or loading heavy shell functions. It has no gemsets: each installed Ruby has its own gem directory, and Bundler's lockfile isolates each project.

open as a page

A project's .ruby-version pins 4.0.7 under rbenv, yet a newly opened terminal runs the system Ruby there; how do you diagnose and fix it?

level: seniorimportance: should knowfreq 35%
basics
~20 s

Check that ~/.rbenv/shims comes first on PATH with type -a ruby; usually the rbenv init line sits in a startup file that shell never reads, or a later PATH edit wins. Then run rbenv version to spot a stray RBENV_VERSION.

open as a page

In a composer.json, how do you configure psr-4 autoloading for your own code, and what does requiring vendor/autoload.php give you?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Map a namespace prefix to a directory under autoload.psr-4, for example "App\": "src/", then require vendor/autoload.php once at the entry point. That file registers Composer's class loader for your code and every dependency, and includes any files entries.

open as a page

In Composer, what is the difference between composer install and composer update, and which one should a deploy run?

level: juniorimportance: must knowfreq 75%
basics
~10 s

composer install installs the exact versions in composer.lock; composer update re-resolves composer.json's constraints, rewrites composer.lock with the newest allowed versions, then installs. Deploys and CI run install, production with --no-dev; developers run update deliberately.

open as a page

In a composer.json, what is the difference between require and require-dev, and when are require-dev packages not installed?

level: juniorimportance: must knowfreq 70%
basics
~20 s

require lists packages the code needs at runtime, installed everywhere and passed on to the package's consumers. require-dev lists test and tooling packages; it is root-only, so a dependency's dev list is never installed, and --no-dev builds skip it.

open as a page

In Composer, what does composer dump-autoload -o change about how classes are found, and why is it for production rather than development?

level: middleimportance: must knowfreq 55%
basics
~20 s

dump-autoload -o scans PSR-4 and PSR-0 directories and writes every class into the classmap, so known classes resolve by array lookup, not a filesystem check. It suits production, where code changes only at deploy, not development.

open as a page

In a composer.json constraint, how does ^1.2 differ from ~1.2, and how do ^1.2.3, ~1.2.3 and ^0.3 behave?

level: middleimportance: must knowfreq 65%
basics
~10 s

In Composer, ^1.2 and ~1.2 are the same range, >=1.2.0 <2.0.0. They differ with three parts: ~1.2.3 means >=1.2.3 <1.3.0 while ^1.2.3 means >=1.2.3 <2.0.0. For 0.x, ^0.3 means >=0.3.0 <0.4.0.

open as a page

What is Packagist, and what does publishing a first PHP library to it involve?

level: juniorimportance: must knowfreq 55%
basics
~20 s

Packagist is the public package registry Composer queries by default. To publish, push a repository with a valid composer.json named vendor/name, submit its URL on Packagist, and tag releases; Packagist reads versions from tags and branches.

open as a page

You pushed tag v1.3.0 of a PHP library on Packagist, but consumers' composer update does not offer 1.3.0; what do you check?

level: middleimportance: should knowfreq 30%
basics
~20 s

First check whether Packagist re-read the repository, usually a missing hook. Then check whether the tag was skipped for an invalid name, a mismatched version key or missing composer.json. Last, check the consumer's constraint, stability settings and repository order.

open as a page

How does Packagist turn a Git repository's tags and branches into Composer versions such as 1.2.0, 2.x-dev and dev-main?

level: middleimportance: should knowfreq 40%
basics
~20 s

Each valid tag becomes a release version, compared without its leading v, with any -beta or -RC suffix setting stability. Each branch becomes a dev version: 2.x becomes 2.x-dev, other names become dev-name, and extra.branch-alias can map dev-main to 1.0.x-dev.

open as a page

On Packagist, how do you retire a PHP package by marking it abandoned with a replacement, and what do consumers' Composer runs then show?

level: seniorimportance: should knowfreq 25%
basics
~10 s

Mark the package abandoned, optionally naming a replacement package, rather than deleting it. Existing versions keep installing, but Composer warns that the package is abandoned and suggests the replacement, and composer audit reports it.

open as a page

Packagist.org serves only public packages; how should a team distribute private PHP packages to its own projects instead?

level: seniorimportance: should knowfreq 32%
basics
~20 s

Keep private packages off Packagist.org and serve them from a private repository: individual vcs entries for a few packages, a static registry built with Satis, or a hosted private registry. Credentials go in auth.json or environment variables.

open as a page