Build Or Depend? Managing Dependencies in Software Development
Today, I want to share my thoughts on managing dependencies in software development.
Dependencies: A Holy Grail or Pure Evil?
Let’s be honest: Nobody starts from scratch when implementing applications in 2025.
Or do you?
Well, here’s to opposite extremes. Some developers tend to pile up dependencies like they are nothing. Others don’t want any dependencies in their code and prefer writing everything themselves.
Taking on dependencies and implementing everything yourself are risks. Both options can cost your project success.
In this week’s newsletter issue, I will share my real-world experience managing dependencies properly in software projects.
Approach 1: No Dependencies at All Cost
We’ve seen it all; most likely, we’ve been part of projects like this. There is an architect who absolutely hates dependencies. They treat them as evil possessions you should never touch as a software developer.
But why?
They mostly see the challenges and risks that come with depending on other people’s code.
For example, what if development stops? What if there is a security issue? What if a currently free library turns into a paid product?
Sometimes, it’s also mixed with: Others don’t know how to write good code - we need to write it ourselves, otherwise, it’s bad code.
That’s a dramatic view of dependencies, and it’s a costly view.
Yes, not taking on dependencies is also taking on dependencies. You depend on yourself to maintain the whole product.
Will you fix the security issues in your code faster than the library maintainers?
Are your developers really better than those who implemented a library for precisely what you need to do? Do you really want to write your own CSV parser, HTTP client, UI library, report generator, OR mapper etc.?
In the end, that means spending more time working on things that don’t directly benefit your business case, but that must be done.
There is the cost of owning and maintaining code. Why would you want to increase the code base size when you could solve the same business problem with half or a quarter of the code?
Reinventing the wheel isn’t a good trait in any profession. Why would you do it as a software developer?
For example, you want to create an HTTP request from your web server to an API. Would you implement the HTTP protocol yourself?
I’d never do that. Luckily, in .NET development, we have robust and highly performant APIs for most common tasks built into the framework/platform.
What about user interface technologies? Would you want to write HTML and CSS from scratch, deal with browser compatibility, rendering performance, and design systems, or do both?
Also, consider new developers joining your team. They will have to learn and understand the modules written for problems others have solved.
You’ll find a developer proficient in Entity Framework Core, allowing them to be productive from day 1. Or you can send them to a training camp to learn about your DIY solution for two weeks.
You will waste a lot of time doing that. It’s better to build on what others have built before you.
Approach 2: The dependency lover
The other extreme is developers taking on dependencies like they are nothing and do not come with certain responsibilities or costs in the future.
I have seen this prominently in JavaScript-based frontend projects.
I understand that the ecosystem is different from the .NET ecosystem. The packages are a lot more focused and smaller. There are many (more) different options available.
Taking a dependency that generates a unique ID can be a valid choice. However, I’ve seen projects that depend on utility libraries and only use one or two functions.
With too many dependencies, you risk getting into a complicated situation. For example, you end up with libraries A and B depending on C. And if development on A continues, they will require a version of C that is different from B.
I always advocate for wisely choosing what you want to develop yourself and what you want to take on as a dependency.
If you only need a fraction of a library, you could end up with a more maintainable code base by implementing that function or method yourself.
Just make sure managing dependencies is not becoming a nightmare and that you spend more time resolving version mismatches or updating libraries in a specific order.
Approach 3: A sensible, responsible approach to managing dependencies
Focus on what’s essential in your business. Write the code that solves your business case, and use dependencies to facilitate and accelerate common software development areas with great solutions.
Don’t reinvent the wheel. Benefit from the knowledge and products other people buy before you.
Consider a modern car company. Do you think Audi or Porsche build their cars from the ground up? Do you think they assemble their computer chips for their driving assistance and entertainment systems? Do you think they produce their tires? No.
​A global car manufacturer may have more than 18,000 suppliers providing 20,000+ different parts.​
You always have to calculate the cost of developing a module or part of a system yourself vs. taking on a dependency that solves the problem for you. Learn that both options have their cost.
When it comes to choosing dependencies, I like to focus on the following topics in this order:
- License:Â I usually work on commercial projects, and I want to use libraries that are free to use for commercial projects (or have a reasonable license and price). I mostly prefer Apache 2.0 or MIT licenses. Just make sure you understand the license of any dependency.
- Activity:Â Is the library in good shape and regularly updated? Is there an active community around the library responding to questions and providing feedback, fixing bugs, etc.?
- Reputation: Is the library well-known in the industry, or the language/platform I’m using? I tend to favor “industry standards” over newcomers. The more people use it, the safer it is to assume development will continue. Otherwise, there are many developers in the same situation as you.
- Ownership:Â Who owns the repository? Is it a well-known person in the industry? What background does the person have? Is the person interested in long-term success of the project, for example, do they run a company that depends on the library?
- Dependencies:Â What transitive dependencies does that library add to the project? I tend to favor libraries that solve a single issue and do not have dependencies. It allows me to exchange the library in case there is something better or development stops in the future.
- Focus: What problem does the dependency solve? Is there a clear goal, and does it align with what I need for my project? I don’t want to depend on a library that bloats my application and develops in different directions every month.
- Ownership-Ability:Â In case development stops, am I willing to continue development and take ownership to facilitate a gradual migration towards another solution?
I could ramble on this topic for a lot longer. As you can tell, I’m passionate about it.
However, I hope this newsletter issue gave you a great overview of the decision-making process for your application and helps you make responsible decisions for your projects.