I was expecting some pushback, but all I got was something I should have seen coming and covered in the original piece. Here’s the follow-up to get it covered.
Every time you tell someone that deep imports are a bad idea, there’s always one reply waiting in the wings: But deep imports perform better.
It sounds plausible. It feels intuitive. But it’s wrong.
To be fair, this myth didn’t come from nowhere. In the past, some libraries really did ship poorly structured entry points with giant index.js barrels with side effects, no tree‑shaking - a build‑time optimisation that removes code you never use from your final JavaScript bundle - support, and no clear separation between public API and internal implementation. In those cases, deep imports sometimes felt like a workaround for bad library design rather than a choice.
Even if it was right, it would have to be a massive performance improvement to justify poor architectural decisions which hamper change.
Runtime performance doesn’t care about your import path
Once a module is loaded, the runtime cost is identical whether you imported it from the package root or use a deep import. JavaScript engines don’t reward you for bypassing the public API. There’s no fast lane for deep imports. There’s just the same module, loaded the same way, doing the same work.
The only thing you’ve optimised is your ability to break when the package author reorganises their folders.
Build performance gains are imaginary or microscopic
Modern bundlers already know how to tree‑shake, dedupe, and optimise module graphs. They don’t need your help. Importing from the package root doesn’t force them to pull in the entire universe; they’re smarter than that.
In fact, today’s tooling increasingly assumes the opposite. Conditional exports, exports maps, and pre‑optimised entry points exist specifically so package authors can define stable, efficient public APIs. Deep imports don’t help these tools, they often bypass the very optimisations designed to make builds faster and more reliable.
At best, deep imports save you a few milliseconds. At worst, they bypass pre‑optimised entry points and make your build slower. Either way, the difference is so small that it’s not worth the architectural debt you incur by coupling your code to someone else’s directory structure.
The trade‑off isn’t even close. You’re not choosing between “fast but fragile” and “slow but safe.” You’re choosing between “fragile for no reason” and “safe with no measurable downside.”
Deep imports don’t perform better. They just break more easily.

Comments
Post a Comment