Why You Keep Overcomplicating Things

I keep seeing this pattern on every dev forum I frequent. Someone posts about a bug that's been eating their week, and the answer almost always comes down to the fact that they built the problem into their toolchain. This is exactly what Your Drug May Be Your Problem means, and it's been true since the early days of choosing between jQuery plugins and raw DOM manipulation. The core issue is dependency bloat. You install a package because it solves one thing, then you end up importing eight nested dependencies, each pulling in more, until your project has more external code than your own. A few years back I was working on a deployment pipeline for a small SaaS product. We had a Node.js app that used something like fourteen packages just for basic string formatting and date handling. The bundle size was absurd, and the app took nearly 40 seconds to start in production. I stripped it down to zero external string utilities and cut startup time to under six seconds. That's not a clever trick, it's just the math of how much code actually runs during cold starts.

Your Drug May Be Your Problem in Practice

Here's how this shows up in real work. You pick a framework because it's popular. Then you spend three weeks configuring it instead of building the feature. Then you hit a version mismatch error and suddenly you're debugging another team's code. This is the loop. I've been doing this long enough to recognize the telltale signs before the project even becomes unmanageable. The most common trap I see is the dependency chain problem. Let's say you're using a state management library that depends on a serialization library, which depends on a polyfill for something your runtime already supports. You didn't ask for any of that, but it came with the first package. A developer on my team once hit a production crash that took us six hours to diagnose. The root cause was an outdated cookie parsing utility bundled inside a frontend auth library we used. The library hadn't been updated in two years, but it was pulling in a dependency tree that included a package with a known edge-case bug around RFC-compliant domain parsing. We didn't find it by reading the docs. We found it by running npm ls on the entire tree and realizing we had three different versions of the same parser installed, each one handling a malformed cookie slightly differently. Another issue is the abstraction leakage that nobody talks about. Every layer of abstraction you add will eventually fail at exactly the wrong moment. A build tool that seems convenient during development will have very different behavior when you're shipping to production, especially with caching and tree shaking. I learned this the hard way with a project that used a bundler with aggressive dead code elimination in dev mode but disabled it in production. We had dead code in our production bundle that was slowing down parsing by roughly 200 milliseconds per request. Two hundred milliseconds on every page load for a site getting tens of thousands of daily visitors. That adds up fast.

There's also the configuration drift problem. You set up a tool with a bunch of custom settings, then you upgrade it and half the settings behave differently or break entirely. This is extremely common with task runners and linters. I've seen teams spend an entire sprint chasing down errors caused by a minor version bump because the team hadn't pinned their dependency versions properly. Pinning versions isn't optional if you want reproducibility. It's just basic hygiene.

Get the Full Details

Your Drug May Be Your Problem, Revised Edition - Hachette Aotearoa ...
Your Drug May Be Your Problem, Revised Edition - Hachette Aotearoa ...

How to Actually Fix This

The first step is usually painful because it requires admitting the current setup is the bottleneck. Audit everything you're depending on right now. Run a full dependency tree dump and look for anything you didn't intentionally install. Most people find that half their packages are transitive dependencies they never knew about. Then evaluate each one against a simple criterion: does this do something my project needs today? If the answer is no, remove it. If the answer is yes, consider whether you could replace it with something simpler or nothing at all. This is where most projects get a massive win for very little effort. In my experience, removing unnecessary dependencies typically reduces build times by 30 to 60 percent and shrinks the production bundle by a comparable margin. Next, pin your versions. Use a lock file and commit it. Don't treat dependency management as something you figure out later. Locking prevents surprise breaking changes from sneaking in during routine updates. I also recommend running automated dependency audits in CI. That way you catch known vulnerabilities before they reach production, instead of finding out about them from a security team email at 2 AM.

When you do need external packages, prefer smaller, single-purpose libraries over heavy frameworks. A well-maintained utility package with ten thousand downloads per week is often more reliable than a popular monolithic framework that hasn't been updated in months. Popularity doesn't equal quality. Maintenance activity does. Look at commit history, open issue count, and the responsiveness of the maintainers. These signals matter more than the star count on any given repository.

When to Walk Away From the Tool Entirely

Sometimes the right answer isn't better configuration, it's switching tools altogether. If you've spent more time wrestling with your stack than building actual product features, the stack is the problem. I've seen this happen repeatedly. A team will fall in love with a framework because of how elegantly it solves a specific problem, then spend six months trying to make it work for problems it wasn't designed to solve. The brutal truth is that most tools are good at a narrow set of things. That's intentional. The problem is the gap between what a tool does well and what your project actually needs. When that gap gets too wide, you're going to fight the tool constantly, and the tool will win. I've recommended rolling my own solution instead of fighting a framework in cases where the framework was fundamentally misaligned with the requirements. Yes, it takes more upfront time. But the ongoing cost of maintaining a workaround inside a broken abstraction is usually far worse than building a simple custom solution from scratch. There's also a psychological component to this. You become attached to the tools you know. It feels safer to keep using something familiar even when it's clearly the wrong choice for the current problem. Recognizing that attachment is the first step toward making a rational decision. Write down the specific problems the tool is causing you. If the list is longer than the list of problems it's solving, that's your answer. It's not loyalty, it's just inertia.

Your Drug May Be Your Problem: How & Why to Stop Taking Psychiatric ...
Your Drug May Be Your Problem: How & Why to Stop Taking Psychiatric ...