heroku-buildpack-ruby: how the classic Ruby buildpack detects and installs your app
Heroku's classic buildpack for Ruby apps
At a glance
- What is it?
- Heroku's classic Ruby buildpack identifies an application by two root files, installs dependencies with Bundler in deployment mode, and derives process types from the Procfile. It is a narrow tool with a narrow contract, and it is worth understanding that contract before you point your app at it.
- Who is it for?
- Adopt heroku-buildpack-ruby when your application is a Rack or Rails app whose dependencies are already pinned in a Gemfile and Gemfile.lock, and when you want Heroku to run Bundler for you at build time. Do not adopt it for a project that needs a hand-written build step, a non-Bundler dependency manager, or a platform other than 64-bit Linux.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Gemfile and Gemfile.lock are the entire detection contract
The buildpack does not look for a Ruby version file, a framework convention, or a config directory. It checks the root of the pushed source tree for exactly two files. The README states that the buildpack detects your app as Ruby if it has a `Gemfile` and `Gemfile.lock` files in the root directory, and the sample output in the README confirms it with the line `-----> Ruby app detected`. There is no documented fallback for a project that has a Gemfile but no lockfile.
That narrowness has consequences. Bundler is the dependency manager the buildpack uses, and the lockfile is what makes the install reproducible, so the pair is treated as the proof that the project is ready for a build. A project that vendors gems without using Bundler, or that manages dependencies with a different tool, will not be recognized by this buildpack at all. The README describes the project as a buildpack for Ruby, Rack, and Rails apps, so the intended audience is a team that has already committed to Bundler as part of its normal workflow.
The practical takeaway is that this buildpack is a thin adapter around Bundler, not a Ruby installation wizard. Whatever the surrounding platform does about language runtimes, the dependency step the README describes is plain `bundle install`.
Dependency installation runs bundle install with the deployment flag set
Once detection succeeds, the buildpack sets up the environment for ruby and Bundler and then runs the install step. The sample output in the README shows the exact invocation the buildpack uses.
Running: bundle install --without development:test --path vendor/bundle --deployment
Fetching gem metadata from http://rubygems.org/..
Installing rack (1.3.5)
Using bundler (1.1.rc)
Your bundle is complete! It was installed into ./vendor/bundle
Cleaning up the bundler cache.Two of those flags shape the whole build. The `--deployment` flag is what makes the install follow the lockfile strictly and fail rather than resolve new versions, which is the correct default for a deployed application and a common source of surprise for a developer who expects a local `bundle install` to update gems. The `--without development:test` flag excludes two groups of dependencies from the build output, so a gem needed only in development is never fetched onto the dyno.
The gems are installed into `vendor/bundle` rather than a shared system location, and the buildpack then cleans up the Bundler cache. The README does not explain whether that cache cleanup affects rebuild speed, and it does not document a way to override the install flags from an application level config, so if your build needs different Bundler behaviour you need a fork rather than a setting.
Process types come from the Procfile, and console and rake are the fallback
After dependency installation, the buildpack turns to process types, which is the part that decides what Heroku actually starts for your app. The README output shows the discovery step and its result.
-----> Discovering process types
Procfile declares types -> (none)
Default types for Ruby -> console, rakeSo the source of truth is a `Procfile` in the repository root. When one is present, the declared types win. When none is present, the buildpack falls back to a small default set for Ruby, consisting of `console` and `rake`. That fallback is deliberately minimal and it does not include a `web` type, so a project without a Procfile builds successfully and then has nothing to serve traffic with.
For a Rack or Rails application this is the detail to get right before the first push. A missing or misnamed Procfile entry is not a build error, it is a runtime surprise much later, when the dyno comes up with no process type to run. The repository also contains `hatchet.json` and `hatchet.lock`, the Hatchet files that drive the integration test suite described in the Hacking section, so the process type behaviour is exercised by the project's own tests rather than only by hand.
The buildpack refuses to run anywhere except 64-bit Linux
The README states plainly that this buildpack requires 64-bit Linux. There is no fallback path described for other architectures, no emulation note, and no warning section about what happens on a different platform. That single line is the clearest statement of the buildpack's scope in the whole README, and it sits above the usage instructions rather than buried in a note.
For the intended audience this is rarely a live constraint, since the target is a Heroku build environment. It matters in two places. The first is local verification: the project's own test workflow runs the buildpack against real app builds, and the README points that workflow at the Hatchet tooling rather than at a local simulator, so testing happens through the platform rather than on a laptop. The second is forks. Anyone modifying the buildpack inherits the same constraint, because the platform that executes it is what defines the environment.
The README does not discuss how the buildpack selects a Ruby version. It says the buildpack sets up the appropriate environment for ruby and Bundler, and the sample output mentions the Bundler version it used, but no version selection flag, `.ruby-version` handling, or runtime list appears anywhere in the README.
Changing the buildpack means forking it and repointing heroku create
The Hacking section is short and it tells you exactly how to work on the code. You fork the repository on Github, push your changes to that fork, and then create a test app pointing at the fork rather than at the published buildpack. The README gives the form of that command as `heroku create --buildpack <your-github-url>`.
This matters because there is no configuration surface for the buildpack itself. The standard usage path passes `--buildpack heroku/ruby`, and the fork path substitutes a URL. Anything else you want to change, from the install flags to the process type defaults, has to be made in code and then published through a fork.
The repository layout supports that kind of work. There is a `lib/` directory, a `bin/` directory, a `Rakefile`, a `spec/` directory, an `.rspec` file, a `.standard.yml` configuration for the Standard Ruby linter, a `buildpack.toml` file, and a `Gemfile` with a matching `Gemfile.lock` for the buildpack's own dependencies. The README documents two commands for that workflow.
$ bundle exec hatchet install$ bundle exec rake specThe first installs the Hatchet tooling and the second runs the spec suite. A `CHANGELOG.md` file and a `changelogs/` directory sit alongside it, which is the same place to look when you want to know what changed in a given release.
MIT licensing, frequent releases, and what the changelog is for
The project is published under the MIT licence, with a `LICENSE` file at the top of the repository and a `CODE_OF_CONDUCT.md` and `SECURITY.md` alongside it. An MIT licence is permissive, so a fork can be modified and redistributed with attribution, which is exactly what the documented forking workflow requires. Nothing in the README adds obligations beyond the licence text itself.
On cadence, the recent release list shows three tagged releases in the space of a few months: v361 on 2026-06-11, v362 on 2026-08-26, and v363 on 2026-10-16. The repository is not archived, and the last push was on 2026-10-16. That means a team can expect the buildpack to keep moving, and it also means that the version your app was built with can change without you touching the application repository.
For a production application that raises a practical question about pinning. The README does not document a way to pin a buildpack version in the application repository, so if you need a reproducible build you have to note the release you deployed against and check the changelog entries in `CHANGELOG.md` when you upgrade. The build output itself gives you the Bundler version that was used, which is the one piece of version information the README shows you directly.
Editorial conclusion
Adopt heroku-buildpack-ruby when your application is a Rack or Rails app whose dependencies are already pinned in a Gemfile and Gemfile.lock, and when you want Heroku to run Bundler for you at build time. Do not adopt it for a project that needs a hand-written build step, a non-Bundler dependency manager, or a platform other than 64-bit Linux. Before switching, verify the Bundler version your lockfile expects against the version the build output reports, confirm that your Procfile declares every process type you intend to run, and check that your build completes under the deployment flag, since the README does not document a way to change the install flags from outside the buildpack.
Frequently asked questions
How does heroku-buildpack-ruby decide that an app is a Ruby app?
It checks the root of the pushed source tree for a `Gemfile` and a `Gemfile.lock`. The README states that detection succeeds when both files are present in the root directory, and the sample output shows the `-----> Ruby app detected` message.
Which Bundler command does heroku-buildpack-ruby run during the build?
It runs `bundle install --without development:test --path vendor/bundle --deployment`. The gems are installed into `vendor/bundle` and the Bundler cache is cleaned up afterwards.
What process types does heroku-buildpack-ruby use when there is no Procfile?
The default types for Ruby are `console` and `rake`, as shown in the build output. A `Procfile` in the repository root overrides those defaults with the types it declares.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/heroku-heroku-buildpack-ruby)Was this useful?