What is a gem and how does Bundler work?

Ruby 2 min read
Short answer

A gem is a packaged Ruby library. Bundler reads a Gemfile, resolves compatible versions, records them in Gemfile.lock, and guarantees every machine installs the same set.

ruby
# Gemfile
source 'https://rubygems.org'

gem 'sinatra', '~> 4.0'
gem 'rspec', group: :development
bash
bundle install       # install and write Gemfile.lock
bundle exec ruby app.rb

#Why bundle exec

It runs the command with exactly the gem versions in your lock file. Without it, Ruby picks the newest installed version of each gem, which may not be the one your project was tested against.

#Version constraints

ruby
gem 'rails', '7.1.3'      # exactly this
gem 'rails', '~> 7.1'     # >= 7.1, < 8.0
gem 'rails', '~> 7.1.3'   # >= 7.1.3, < 7.2
gem 'rails', '>= 7.1'     # anything newer — avoid

~> is the pessimistic operator. It allows patch and minor updates but stops before the next breaking major version, which is what you usually want.

#Gemfile vs Gemfile.lock

The Gemfile says what you want, usually as a range. The lock file records what you got, exactly, including every transitive dependency.

Commit both. bundle install respects the lock; bundle update re-resolves and rewrites it.

#Useful commands

bash
bundle update nokogiri     # update one gem, leave the rest
bundle outdated            # what has newer versions available
bundle exec rspec          # run a tool from the bundle
gem install rails          # global install, outside any project

#Groups

ruby
group :development, :test do
  gem 'rspec'
  gem 'pry'
end
bash
bundle install --without development test

Skips the ones a production server does not need.