Ten years ago, I wrote Component-based Rails Applications. Today, on cbra.info, I have this banner: "I consider the CBRA approach deprecated. Gradual modularization based on packages gives us all the benefits of components (and more) for much lower costs."

Gems and engines still play an important role, just not as the path but rather as the destination.

I wrote yesterday in What is the modularization destination for large apps? that the destination for every package in a gradual modularization context wants to be either application or library. As part of that argument, I shared this diagram containing three significant points on the gradual modularization extraction axis:

Diagram of a Continuum from *not extractable* to *extractable* to *extracted*

I can use this axis to explain why the CBRA approach for getting to extracted code should be deprecated. Adding the space in which packages and gems work well, the following comes up for me:

Packages and gems in relation to the extraction continuum

The green areas are where the technology shines. I am using the gradient to indicate where I think the technology gains or loses its power.


The first thing to note is that packages shine where we work toward extractability. That's obviously because of the ability to have, acknowledge, but not do anything about violations. I continue to believe that this is the core technical innovation packwerk contributed to application architectural work. This capability allows packages to occupy the in-between space of entanglement and separation, the prerequisite to extraction.

As Gannon McGibbon writes in A Packwerk Retrospective, when they tried to extract a package that didn't contain any violations, they couldn't do so immediately. They had to do more work to make it extractable because of entanglement that packwerk couldn't see. For this reason, I am starting the gradient for packages' before the axis reaches extractability.

We know packwerk can not see a bunch of stuff:

  1. Non-zeitwerk-controlled code
  2. Metaprogrammed class-references both in production code as well as in test code
  3. Code in gems

Note that point no 3 is not what packwerk or gradual modularization are after at their core, but it is still interesting to add to the list (if only to inspire future thought of where the tooling and its usefulness might go)

It is important to note that both points no 1 and no 3 are solved by pks, a rust implementation of packwerk. The reason pks can do this is that it does not rely on zeitwerk to link filenames to and from constants. Instead, it parses all the files in the project (and optionally gems). And because it is built exploiting rust's ability to go fast... it is still faster than packwerk.

So, with pks instead of packwerk, we can push the gradient (the applicable area) for packages to the right.

Practices can also push the gradient of packages to the right. As two examples, look at these PRs on the repo for this website:

I am currently enforcing this practice via convention rather than any tools. I will make it the topic for another day to discuss the tradeoff regarding this decision.


The Component-based Rails Applications (CBRA) lays out how to use gems to create internal structure for Ruby and Rails applications. A whole host of companies have tried to make this approach work. Some do so successfully still today. Many did not make it work. They perceived the approach as too heavy-handed, too ceremony-laden.

One side of this heaviness is that in using gems for CBRA, we want only a portion of what gems offer and require. The part we don't need creates unnecessary overhead.

Today, I believe that the even greater hurdle is that gems don't help with extraction. The opposite is true: the extraction needs to have already happened for gems to be applicable because they don't offer tools to get to extractability. They do allow us to manifest it.

As such, I start drawing the gradient for gems at the point of the code's extractability. Moving to the right towards extracted is where we start to use all of gems' capabilities, and that is where gems shine.

gradual modularization (21) gems (1) engines (1)


Mention this post from your site:

Except where otherwise noted, content on stephanhagemann.com is licensed under CC BY 4.0 by Stephan Hagemann