Writing code is easy. Dealing with the the wrong dependencies down the line is hard, and can cost hundreds or thousands of hours to clean up when you suddenly need to. Spend time actively managing your dependencies - for any lasting software, this'll save both time, risk and money in the long run.

These days, introducing a new dependency on external packages is as simple as a little terminal command. Be it dotnet install, npm install, or any other, they all do the same thing: They pull down packages from a package repository where anyone can upload their packages. It's so fast, and so easy. You just saved yourself an hour of writing code, by spending ten seconds installing a package.

Three years down the line, and there'll be some major framework upgrade. Or new language version. Or you're switching to another underlying platform. Or you're trying to refactor something. But this package you now depend on, limits you from this - for any reason. And your entire application is built upon it.

Now, not only do you have to spend time to re-learn the whole problem domain this package solves completely out of context, you also need to find a way to upgrade or replace it.

It may be easy. Or it may be incredibly demanding. It can take five minutes, or it can be six months of rewrites. As with everything else, it depends. And this you'll have to do while also supporting the application in production.

Spending an hour writing some code doesn't seem so bad, now, does it?

We've seen it over and over. The left-pad issue, how log4net's mangled versioning scheme confused millions of people, is-promise and event-stream. Developer platforms like Episerver (Optimizely now) has been stuck on legacy versions of the .NET Framework, wasting thousands and thousands of developer hours trying to deal with the problem. If you're in the .NET space and depend on Newtonsoft.Json, chances are you've already been in versioning conflicts with other dependencies, as it's a heavily used package in all kinds of things.

Sometimes, it's not about difficult dependency graphs. Sometimes it's just not knowing the extent of what a package does and does not. A popular package in the .NET-space, AutoMapper turns compile time errors into runtime errors, and it doesn't tell you before it breaks production.

DRY - Do Repeat Yourself

This whole speech doesn't only go for third party packages. Nowadays it's common to have internal feeds of packages for common functionality. Since you're in control of these yourself, they are usually not too difficult to deal with. But once you're maintaining several major versions of them for use in production, upgrades can still be troublesome. Sometimes, the easiest solution is simply to Do Repeat Yourself, as opposed to the so often misunderstood and abused Don't Repeat Yourself.

I'm not saying you should never use external packages. Some of them are really good - even some of the ones mentioned above. They might solve a problem you don't know how to solve properly, or they might enable whole new architectural styles for you.

Just stop and think for a few seconds before you reach for that install command. Will it benefit you long term? Or is it just because you're trying to save ten minutes in the moment? Is it really worth it potentially causing hours of trouble down the line, just so you can feel good and write clean code - whatever that means - and finish your job a bit quicker now?