So Many Frameworks, Nobody Remembers Why: A Stack Audit Survival Guide
Picture this: a new engineer joins your team. Smart, motivated, ready to contribute. On their first day, they pull up the repo and start reading through the README. By day two, they've found three different state management approaches in the same codebase. By day three, they've counted four separate HTTP client libraries. By the end of week one, they've stopped asking why things are the way they are and started just copying whatever pattern is closest to the thing they're trying to build.
That's not a new-hire problem. That's a stack problem. And it's more common than most engineering leaders want to admit.
How a Stack Becomes a Graveyard
No team sets out to build an incomprehensible mess. The path to a bloated, incoherent stack is paved with individually sensible decisions made by people who were solving real problems at the time.
Here's how it typically unfolds:
Phase 1: The founding stack. Your first engineers pick tools they know and trust. These are reasonable choices. The stack is small, coherent, and makes sense to the people who chose it.
Phase 2: The scaling additions. As the product grows, you add tools to solve new problems. A caching layer here. A job queue there. A new testing framework because the old one was slowing CI down. Each addition is justified. None of them are removed.
Phase 3: The team expansion. New engineers join, bringing preferences and prior experience. A senior hire strongly advocates for a particular ORM. A new team is spun up and picks their own frontend framework because they move faster with it. Divergence begins.
Phase 4: The drift nobody notices. Frameworks accumulate. Abstractions multiply. The original architectural decisions get buried under layers of additions. The engineers who made those original decisions have mostly left. Nobody left knows why the old patterns exist, but everyone's afraid to remove them.
Phase 5: The new hire reality check. A fresh set of eyes arrives and immediately sees what the team stopped seeing: the system is a maze. Onboarding takes months. Productivity is slow. Attrition follows.
The Real Costs Nobody Is Calculating
Framework sprawl isn't just aesthetically unpleasant. It has measurable costs that most teams are absorbing without realizing it.
Cognitive Overload for New Engineers
Every framework in your stack is a new vocabulary a developer has to learn before they can contribute meaningfully. Multiple competing approaches to the same problem — two ways to handle authentication, three patterns for error handling — don't just double the learning time. They create decision paralysis. New engineers spend energy figuring out which pattern to follow instead of solving actual problems.
Research on cognitive load in software development consistently points to context-switching and ambiguity as primary drivers of reduced output. A bloated stack is a cognitive tax assessed on every engineer, every day.
Security Surface Area
Every dependency is a potential attack surface. Every framework you're running is a framework you need to keep patched, monitored, and updated. The security cost of a sprawling stack isn't theoretical — it's proportional. More tools mean more CVEs to track, more update cycles to manage, and more places for something to slip through.
Hiring and Retention Friction
When your stack is idiosyncratic — a unique combination of frameworks that doesn't map to any coherent modern pattern — your hiring pool shrinks. You can't recruit for engineers who know your stack, because nobody outside your company does. You have to hire for raw aptitude and then invest heavily in onboarding. And if that onboarding experience is chaotic, your best candidates leave for teams with cleaner systems.
Decision Fatigue at Scale
When there's no clear standard, every implementation decision becomes a debate. Should this new service use the old HTTP client or the new one? Which state management pattern should this feature follow? These aren't high-value engineering conversations. They're friction. And they happen constantly in teams with undisciplined stacks.
Real Patterns Worth Recognizing
A few architectural debt patterns that show up repeatedly in teams that have let their stacks drift:
The Legacy Wrapper. An old library that the team wanted to replace got wrapped in an abstraction layer so it could be swapped out later. The replacement never happened. Now the abstraction layer is load-bearing and nobody understands what's underneath it.
The Framework-Per-Team Split. Two product teams picked different frontend frameworks and both shipped. Now you have two separate frontend stacks maintained in parallel, sharing almost nothing, and requiring engineers to context-switch between them.
The Abandoned Migration. Someone started migrating from one database client to another. They got halfway through before priorities shifted. Now half the codebase uses the old client and half uses the new one, and there's no clear path to finishing.
The Experimental That Shipped. A framework was introduced for a proof of concept and was never intended for production. The POC became a feature. The feature became core infrastructure. Nobody wants to touch it.
If any of these sound familiar, you're not alone. They're almost universal at companies past the Series A stage.
The Stack Audit Checklist
Before you can simplify, you need to see clearly. Here's a practical audit process your team can run in a week:
1. Inventory everything. List every framework, library, and tool in your stack. Include transitive dependencies if you can. The goal is visibility. Most teams are surprised by how long the list gets.
2. Assign ownership. For each item on the list, answer: who on the team understands this well enough to maintain it? If the answer is nobody or one person, flag it immediately.
3. Identify duplicates. Highlight every case where two or more tools are doing the same job. Don't make decisions yet — just make the duplication visible.
4. Trace each tool to a decision. For every major framework, try to find the decision that introduced it. Was it documented? Does the rationale still apply? If you can't find the decision, that's data.
5. Measure usage. For frontend libraries and backend dependencies alike, check actual usage. A library imported in three files that could easily be replaced with native functionality is a strong removal candidate.
6. Score each item. Rate each tool on two dimensions: how much value does it provide, and how much complexity does it add? Tools with low value and high complexity are your first targets for removal.
7. Build a consolidation roadmap. Don't try to fix everything at once. Pick two or three consolidation opportunities that are high impact and relatively low risk. Make a plan. Assign owners. Set a timeline.
The Permission to Simplify
Here's the thing about stack audits: the technical work is usually the easy part. The harder part is getting organizational permission to do work that looks like it's going backward.
Removing a framework doesn't generate a feature announcement. Consolidating two HTTP clients doesn't make it into the sprint demo. Simplification is invisible in the same way that good infrastructure is invisible — you only notice it when it's absent.
But the teams that build this discipline — that treat simplicity as a feature worth shipping — are the ones where new engineers get productive in weeks rather than months. Where incidents are easier to diagnose. Where architectural decisions actually stick.
Your stack doesn't have to be a graveyard. But it won't clean itself up. Someone has to decide that the cost of complexity is worth paying attention to — and then actually do something about it.
Start with the inventory. The rest gets easier from there.