Status
Carton’s boundaries work today. Only exports cross, patches to builtin classes stay put, each Carton can bring its own gem versions, and a Carton can leave the app as a gem. Carton remains experimental, as does Ruby::Box. Use Ruby 4.0.7 or later and, with Bundler, Bundler 4.0.20 or later.
Before production
Section titled “Before production”A team should not rely on Carton in production until these change:
Ruby::Boxleaves experimental status. Upstream Ruby. Every process run withRUBY_BOX=1prints Ruby’s experimental warning, and Box behavior may change between Ruby releases.- Cheaper Boxes. Upstream Ruby. Template Boxes (#25) or Boxes started from a resolved load path (Ruby #22275) would lower the cost per Carton.
- Rails reloading. Carton. Rails apps restart on change. A reloading spike rebuilds changed Cartons through private hooks, but the runtime has no reload interface.
- Runtime dependency enforcement. Carton, waiting on Ruby #22275. A Gem Carton sees its Importer’s whole lockfile at runtime; see Dependency enforcement.
To try Carton in an existing app now, follow Adopting Carton, which also covers operations.
Cost per Carton
Section titled “Cost per Carton”A plain Carton costs about 60 ms and 2.4 MB in the current measurements, most of it Ruby::Box.new. Aim for tens of Cartons rather than hundreds. Gem Cartons cost more because they also load RubyGems specifications into their Boxes.
Shared classes and objects
Section titled “Shared classes and objects”Exports are shared objects. Reopening an exported class or changing shared state affects every Importer. carton check warns about class/module definitions through directly followed Imports, but adds no runtime guard and cannot follow aliases or dynamic mutations. See Sharing classes and services and what a Box does not isolate.
Dependency enforcement
Section titled “Dependency enforcement”A Gem Carton’s gemspec declares its dependencies, and carton check reports Undeclared Gems. At runtime, however, it receives the Importer’s whole lockfile. Restricting it to declared dependencies remains deferred while Ruby’s resolved-load-path proposal develops.
Static analysis
Section titled “Static analysis”carton check cannot follow every reflective or generated import. carton rbs leaves Exports it cannot infer as untyped, and RBS has one global namespace for all Cartons. See Types and checks for the supported checks and type generation.
Rails integration
Section titled “Rails integration”The experimental Rails example runs Customers and Billing as isolated Engines, with Carton-owned loaders and an explicit CLI bridge. Domain Cartons load their own Active Support extensions, and the example does not establish compatibility with arbitrary Rails features or third-party Engines.
Ruby bugs
Section titled “Ruby bugs”On Ruby 4.0.7, changing only a builtin method’s visibility (such as protected :upcase on String) leaks from a Box to every other Box (reproduction). This is an upstream Ruby bug, not a Carton limitation.
Possible future features
Section titled “Possible future features”Public sub-entrypoints could let large Cartons expose lazy parts of their Interior. Today only the Entrypoint can be imported. An import graph and a baseline file are also possible tooling additions. These are design options, not a committed roadmap.
Unsupported and private-runtime experiments live in spikes/, including shared-gem loading and Rails reloading. They do not change the supported runtime’s guarantees.
