
Every multisite platform I have worked on gets harder to change
Why multisite drift needs a smaller, shared component library instead of tighter governance, and what has to be true for one to survive real variation.
The pattern
A multisite platform launches with a shared theme and a handful of sites. Two years in, every site has drifted. A department wanted a slightly different card layout, another needed a hero variant nobody else uses, a third has a one-off region that exists because a deadline mattered more than architecture that week. None of these decisions was wrong on its own. The sum of them is a platform where changing anything shared now means auditing every site to see who quietly forked the thing you’re about to touch.
The instinct at that point is almost always governance: a design system document, a review process, a rule that new patterns need sign-off. I’ve watched that instinct play out on more than one higher-ed platform, and it doesn’t hold. Governance slows the drift without stopping it, because the actual incentive that produced the drift in the first place (a real site with a real deadline and a real reason its case is the exception) never goes away. Rules that survive contact with a deadline are rare, and a document nobody consults under deadline pressure is not architecture. It’s a compliance cost paid by whoever remembers to read it.
What I think actually works
The fix isn’t governing variation harder. It’s shrinking what’s unique per site down to configuration, so there’s less surface for drift to happen on in the first place. A site that can only choose from a defined set of card layouts, hero variants, and colour tokens can still look genuinely different from its neighbours, but it can’t quietly fork the underlying markup to get there, because the underlying markup isn’t something a site owns. The component is. The site picks a configuration of it.
That only works if the shared library is actually built for variation rather than for one canonical look. A component with a single hardcoded appearance and no sanctioned way to adjust it just reproduces the original problem one level up. The first team that needs something the library doesn’t offer will fork it exactly the way they forked the theme, because forking was always the fastest path and nothing about a rigid library changes that.
The strongest objection, and why it’s right up to a point
The real counter-argument is that institutions are genuinely different. A medical school and a business school have different audiences, different content, different visual expectations from their own leadership, and a shared component library, however well designed, will eventually meet a requirement it wasn’t built for. At that point either the library bends until it’s “flexible enough to be useless” (every prop optional, every behaviour overridable, a component that technically does everything and clearly stands for nothing), or the site forks anyway, and you’re back where you started with extra steps.
That’s a real failure mode, and I don’t think a component library avoids it by trying harder to anticipate every future requirement. It avoids it by being honest about which axis of variation is actually sanctioned (colour, spacing, a defined set of layout variants) and treating anything outside that axis as a real signal that the library needs a new variant, reviewed and added once, rather than a private escape hatch reached for under deadline pressure. The difference isn’t flexibility. It’s where the decision about what’s allowed to vary gets made, and by whom.
What that means in practice
This is the actual shape of bootstrap_components: a defined set of components with a
defined set of variants, built so a site chooses from real options rather than owning a
private copy of the markup. The module doesn’t claim to have anticipated every
institution’s requirement. What it claims is a smaller one: that adding a genuinely new
variant to a shared library, reviewed once, is cheaper across a multisite platform’s
lifetime than every site being free to solve the same problem its own way, quietly, as
many times as there are sites.
I don’t think that claim is finished. The variant set the module ships with is a reasonable starting point for the platforms it was built against, not a proof that any axis of variation is the right one for every higher-ed platform. If you’re running a multisite platform where the shared-component approach broke down for a reason that wasn’t “someone skipped the review,” I’d genuinely like to know what it was. That’s the failure mode I haven’t seen yet, and the one that would change my mind about where the line between sanctioned variation and a real gap in the library actually sits.
What this came from
- ModuleBootstrap 5 Components