Where to Let Portfolio Apps Diverge From the Foundation
A shared foundation should not standardize everything. Knowing where to let portfolio apps diverge is what keeps the foundation useful instead of a straitjacket.
A shared foundation that tries to standardize everything strangles the products it is supposed to help. The skill is not maximizing what is shared. It is drawing a clean line: standardize the parts that should be identical across every product, and deliberately let products diverge on the parts that make them different. Get that line wrong in the direction of too much sharing and your foundation becomes a straitjacket people route around. The foundation's job is to remove undifferentiated work, not to make every product the same.
What should a shared foundation not standardize?
It should not standardize the product. Standardize the plumbing, let the product be itself. The reliable rule: share the things every product needs to be identical on, and leave the things that are each product's reason to exist.
Standardize hard, no divergence allowed:
- Auth and identity. Every product authenticates the same secure way. There is no good reason for product B to invent its own login.
- Deploy and infrastructure. One pipeline, one hosting pattern, because one runbook has to cover everything.
- Billing and payments. The machinery of taking money is the same problem everywhere.
- Logging and monitoring, so you can watch the whole portfolio from one place.
Let diverge, freely:
- The core product logic. This is what makes each product different. It should be different.
- The domain model. A bookkeeping product and a music-coordination product have nothing in common at the data level, and forcing a shared model would wreck both.
- The user experience of the actual features, as opposed to the shared UI primitives underneath them.
- Release cadence, where products genuinely need different rhythms.
The pattern: the closer something is to the product's reason for existing, the more it should diverge. The closer it is to undifferentiated plumbing, the more it should be shared. This is what belongs in a shared foundation drawn from the other direction, by naming what does not.
Why forcing standardization backfires
When a foundation over-standardizes, it forces products to conform on things that should be free. A product needs a data model the shared schema does not allow, so it fights the schema. A product needs a flow the shared framework did not anticipate, so it hacks around the framework. Every one of these battles makes the product worse and the foundation more complicated, because the shared layer grows special cases to accommodate the divergence it should have allowed in the first place.
The result is the worst of both worlds: products that are constrained and a foundation that is bloated. The tell is a shared component full of flags that only exist because the foundation refused to let products diverge cleanly. That bloat is one of the mistakes that quietly rot a foundation, and it comes directly from confusing "standardize the plumbing" with "standardize everything."
Over-standardization also kills the thing a portfolio is for. The reason to run different products is that they are different. If the foundation flattens them into variations of one template, you have lost the point.
The paved road, not the locked gate
The healthy model is a paved road. The shared foundation is the easy, default, well-maintained path for everything undifferentiated. Products drive on it for auth, deploy, billing, and infrastructure because it is genuinely the best available option, not because they are forced. And where a product needs to leave the road for something product-specific, it can, cheaply and locally.
This is why I build the foundation as thin glue over standard tools rather than a framework products are trapped inside. Glue lets a product diverge on its domain logic while still inheriting the shared plumbing. A framework forces conformity all the way down, which is exactly the straitjacket you are trying to avoid. The paved road beats the free-for-all, but only because it is a road you can choose to leave, not a cage.
Draw the line on purpose, and revisit it
The line between standardized and divergent is a decision, not an accident, and it moves over time. Something that starts product-specific might become universal once three products need it, at which point it earns its way into the shared layer. Something in the foundation might turn out to serve only one product, at which point it should be pushed back down.
I keep the line honest by making both directions cheap. Promoting a pattern into the shared foundation and localizing something back into a single product are both fast operations in my setup, so Bootspring lets me move the line as the portfolio teaches me where it belongs. The foundation stays lean, the products stay free where they need to be, and the shared layer holds only what genuinely deserves to be shared. That balance is the whole art of running many products on one foundation.