There's an industry trend to avoid writing code as much as possible, because who has time to write eight lines when a stranger has already published a package for it? Turns out that convenience isn't free
TL;DR: Write your code unless you need an existing complex solution
Problems π
- Coupling
- Security problems
- Architectural complexity
- Packages Corruption
Solutions π
- Implement trivial solutions
- Rely on mature dependencies
Context π¬
Recently, there's been a trend to rely on dependencies so hard to trace that you'd need a private investigator, not a debugger.
This introduces coupling into your designs and architectural solutions, which is a polite way of saying you handed strangers the keys to your codebase.
In August 2026, an attacker compromised the maintainer account behind Keyv and injected credential-stealing code into it, right around the time thousands of developers were happily typing npm install without a second thought.
The malware spread through worm-like propagation to at least 444 packages across more than 2 billion monthly installs before anyone noticed, because auditing your transitive dependency tree is apparently nobody's job until it explodes.
You had no way to see this coming just by reading your own code, which was the whole point of importing it instead of writing it.
Sample Code π»
Wrong π«
$ npm install --save is-odd
// https://www.npmjs.com/package/is-odd
// This package has about 500k weekly downloads
module.exports = function isOdd(value) {
const n = Math.abs(value);
return (n % 2) === 1;
};
Right π
function isOdd(value) {
const n = Math.abs(value);
return (n % 2) === 1;
};
// Just solve it inline
Detection π
[X] Automatic
You can check your external dependencies and stick to the minimum, assuming you can list them all without opening a spreadsheet.
You can also depend on a certain concrete version to avoid hijacking, though pinning a version just means you trust yesterday's stranger instead of today's.
Tags π·οΈ
- Security
Level π
[X] Intermediate
Why the Bijection Is Important πΊοΈ
Your design should map to the MAPPER with a clean bijection.
When you pull in an external package for a trivial rule, you stop owning that piece of the model.
The package maintainer's decisions become part of your bijection, whether you reviewed them or not.
You lose traceability between your domain concept and the code that implements it.
A concrete version pin restores part of that bijection, but you still depend on someone else's model matching yours.
AI Generation π€
AI code generators often suggest importing a popular package for problems you could solve in a few lines.
They pattern-match toward the most common solution in their training data, which is usually "there's a package for that."
Ask an assistant to check if a number is odd, and it may reach for a library instead of a single modulo operation, because apparently, even parity checks need a supply chain now.
AI Detection π§²
AI generators rarely flag unnecessary dependencies on their own.
They don't weigh the coupling cost of a package against the cost of writing the trivial logic yourself.
You need to explicitly instruct the assistant to prefer inline solutions for trivial problems and reserve dependencies for real complexity.
Try Them! π
Suggested Prompt: Replace the trivial external package dependency with a small inline implementation that removes the unnecessary coupling
Without Proper Instructions π΅
With Specific Instructions π©π«
Remember: AI Assistants make lots of mistakes
Conclusion π
Lazy programmers push reuse to absurd limits.
You need a good balance between code duplication and crazy reuse.
As always, there are rules of thumb, no rigid rules, and plenty of developers who'll learn the difference the hard way anyway.
Relations π©β€οΈππ¨
More Information π
- Poisoned Packages
- Packages Corruption
- Copyright Threats
- Malware in Packages
- Keyv Supply Chain Attack
Disclaimer π
Code Smells are my opinion.
Credits π
Photo by olieman.eth on Unsplash
Thanks to Ramiro Rela for this smell
Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test, it introduces security challenges, and it causes end-user and administrator frustration.
Ray Ozzie
This article is part of the CodeSmell Series.