The Gemfile Builder generates a Bundler Gemfile for a Ruby or Rails project, with the right gems placed in the right groups. Pick your Ruby and Rails versions, your database, and toggles for authentication, background jobs and testing.
What a Gemfile actually contains
A Gemfile has three layers. First comes a source declaration pointing to RubyGems and a ruby version directive that locks the interpreter version Bundler enforces. Second comes the main gems — for a Rails app this means rails, a database driver, a web server (puma), and any runtime dependencies like redis or devise. Third come the grouped gems: development-only tools like rubocop and testing libraries like rspec or capybara go in group blocks so Bundler can install just what each environment needs.
How it works
The tool assembles these three layers based on your choices:
- Rails vs plain Ruby. A Rails project gets the
railsgem pinned with the pessimistic~>operator, which allows bug-fix releases within the minor version without jumping to a breaking major. A plain Ruby project skips the Rails stack. - Database driver. Choose
pgfor PostgreSQL,mysql2for MySQL or MariaDB, orsqlite3for SQLite. The gem must match yourconfig/database.ymladapter exactly or Rails raises a connection error at boot. - Optional gems. Toggling Devise adds authentication scaffolding; Sidekiq adds background-job processing with Redis as the queue backend. These are top-level gems because they run in all environments.
- Test and development groups. RSpec (
rspec-rails), FactoryBot, Capybara, and Selenium land ingroup :development, :testorgroup :test; rubocop and similar tools go ingroup :development. Production deploys skip these groups entirely.
The ~> operator is central to safe versioning: ~> 7.2 allows any 7.x from 7.2 up but blocks 8.0; ~> 7.2.2 restricts to 7.2.x only. This lets Bundler pick up patch releases automatically while keeping breaking version jumps out.
After generating your Gemfile
Save the output as Gemfile in your project root, then resolve and lock:
bundle install # resolves and writes Gemfile.lock
bundle install --without development test # production deploy (skips dev/test groups)
bundle update rails # bump one gem within its ~> constraint
Gemfile.lock and why it matters
Commit Gemfile.lock for applications. It records the exact resolved version of every gem — direct and transitive — so every developer machine, CI runner, and production server installs identical code. Leave Gemfile.lock out of published gems (add it to .gitignore) so downstream applications can resolve their own consistent set.
Common pitfalls
| Mistake | What goes wrong | Fix |
|---|---|---|
| Database gem mismatch | Rails cannot connect at boot | Match gem to config/database.yml adapter |
bootsnap without require: false | Gem evaluation order issues | Always use gem 'bootsnap', require: false |
| Dev tools outside groups | rubocop loads in production | Place in group :development |
| Forgetting to commit lock file | Different gem versions per environment | Always commit Gemfile.lock for apps |