ruby / ruby/rubygems

Optional support for compiling native extensions for :path gems in monorepos

Open
#9,275 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bundler
Dominant language
Ruby
Stars
4k
Forks
1.9k
Avg merge
1d 2h
Merged PRs (30d)
81

Description

Describe the problem as clearly as you can

Bundler does not compile native extensions for gems declared using the :path source. I understand this is documented and intentional behaviour.

However, this limitation becomes significant in monorepos where many internal gems live side-by-side and are composed via path: dependencies. In our case, gems live under packages/*, and one internal gem includes a native extension implemented in Rust (via rb_sys) and configured using extconf.rb.

Because Bundler does not run extension build steps for :path gems, bundle exec fails at runtime unless the extension is manually built ahead of time, or the dependency is converted to :git or packaged as a gem. Both alternatives significantly degrade the monorepo development workflow.

I am not reporting a bug in current behaviour, but requesting consideration of an opt-in feature to allow native extensions to be compiled for :path gems.

Proposed feature / behaviour

Introduce an explicit, opt-in Bundler configuration that allows native extensions to be built for :path gems, while preserving current behaviour by default.

  • Opt-in only, via Bundler config (global or per-gem), so existing behaviour is unchanged unless explicitly enabled.
  • Out-of-tree builds: native extensions would be compiled into a Bundler-managed build/cache directory rather than writing build artefacts into the working tree.
  • Standard extension pipeline: Bundler would invoke the existing RubyGems extension build mechanism (e.g. extconf.rb, including Rust extensions via rb_sys), without needing Rust-specific logic.
  • Load path integration: the build output directory would be added to $LOAD_PATH ahead of the :path gem’s lib/, allowing require to resolve the compiled extension while Ruby source files continue to come from the local checkout.
  • Monorepo-friendly: this allows internal gems under packages/* to be used via :path without requiring separate manual build steps or switching to :git.

This would preserve Bundler’s rationale for not mutating :path directories while enabling a much smoother workflow for monorepos that include native extensions.

Did you try upgrading rubygems & bundler?

Yes. This behaviour persists on the latest versions of RubyGems and Bundler available at the time of reporting.

Post steps to reproduce the problem
  1. Create a monorepo with multiple gems under packages/*
  2. One gem includes a native extension configured via extconf.rb
  3. Another gem (or the top-level application) depends on that gem using gem "my_native_gem", path: "packages/my_native_gem"
  4. Run bundle install
  5. Run bundle exec ruby -e 'require "my_native_gem"'

The extension is not compiled, and the require fails at runtime because the native library is missing.

Which command did you run?

bundle install
followed by
bundle exec ruby -e 'require "my_native_gem"'

What were you expecting to happen?

With an explicit opt-in configuration, I would expect Bundler to compile the native extension for the :path gem during install, similar to how it behaves for :git or packaged gems, without writing build artefacts into the working tree.

What happened instead?

The native extension is not compiled for the :path gem, resulting in a runtime load error unless the extension is manually built beforehand.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing Bundler's :path dependency handling during bundle install and the existing RubyGems extension pipeline used by extconf.rb. Reproduce the monorepo case with a native extension, then inspect how bundle exec resolves the gem's load path. Done means an explicit opt-in builds outside the checkout and lets require load the compiled extension while default behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby, rust
Domain
build-system, developer-experience, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.