The Hidden Costs of Your Dependencies

The Hidden Costs of Your Dependencies

Summary

Dependencies in our projects have hidden, possibly unthought-of or ignored, costs when added. Dependency management tools like Swift Package Manager (SPM) and NPM make adding a 3rd party library almost too easy. With a few clicks you can import thousands of lines of code into your project and ship that to your users. Great, you got the task done, but at what cost? Did you think of the maintainability of that code, impact to your career growth, security implications, the complexity of what you just brought in, or how about the transitive dependencies?

Using a dependency isn’t always bad, but we should be intentional about how and when we use them and what the trade-offs are.

Note: I am not talking about 1st class dependencies like importing UIKit from Apple. Yes, there can be some similar risks as mentioned below, but those risks are much lower because they are coming from the platform vendor.


The hidden costs

Complexity

First up are the added complexities brought in by each dependency, and some of them are not obvious. Multiply this by however many 3rd party dependencies are being used, and you have the potential for a lot of headache and distraction from more important work. The below items are in no particular order.

The lines of code problem

This may sound silly, but considering each line of code (LOC) added to your project is important. One reason, as mentioned, is that you have to support each line of code that is added, and a given developer can only support so many LOC. Alone, each line added isn’t that big of a deal. If you are considering adding a function with 10 lines versus 9 lines then it doesn’t make that big of a difference in the short term. Multiply this over the course of the year and based on how many people are contributing to a code base and that number becomes a lot bigger. I like to think of it like dropping grains of sand at some location. At some point, you will have a beach, and that beach will have all sorts of garbage mixed in (tech debt, bugs, etc.). It is our job as developers to clean and maintain that beach.

Screenshot showing the options to pick for the local swift package

Add a 3rd party library, and you have just dumped some unknown truckload of sand (and garbage?) on your beach to maintain. If that 3rd party dependency has transitive dependencies, where that dependency has dependencies, then there is even more being brought into your project.

As mentioned, there is only so much sand that we can maintain (aka LOC). It shouldn’t be that surprising to know that there is a limit. Enter R0ml’s law: Each developer can write about 1000 LOC, debugged, each month. That same developer can support about 25k LOC a year. So at a point (~2 years), you would have stalled most new feature development of a project for that developer in about 2 years1. Bringing in a dependency also counts towards the total LOC (even if you discount those lines of code because they are “battle tested”). If that dependency has transitive dependencies…🤯. Like mentioned above, you still have to maintain that code.

Time to hire.

Security

This is one of those subjects, like accessibility, that everyone knows they should be spending more time prioritizing. For dependencies, this means understanding what that code will be doing when integrated into your project. If you don’t audit your dependencies when bringing them in, I know I don’t as much as I should, then you can be bringing in anything. In theory, a dependency, say cough cough Facebook’s sdk**, can be sending up location or any other private user data to their backend for processing. Dependencies can even listen to user entered input or record all interaction in your app. For Xcode projects, don’t forget that any code including a dependency you bring in will have the same permissions that users grant your app. Meaning that if you request, and receive permission, to always access location, then the ability to get the location at all times is readily available to your source code in addition to any 3rd party dependency 🕵️.

Furthermore, if there is a dependency with a security weakness, then you are also vulnerable to that weakness. If a dependencies servers are hacked and they have your user data on them, that is your problem too. From a security perspective, dependencies increase the surface areas for something to go wrong. Remember, your users won’t be blaming your app’s dependencies for doing something shady or leaking data.

**I am not actually sure if their libraries track your location, but I am skeptical about integrating anything made by Facebook/Meta.

Broken windows

The idea of broken windows in software is that others are more likely to follow the established conventions and habits in a code base. If there are a lot of dependencies in a project or the community is dependency oriented (e.g., npm), then that tends to lead to adding more dependencies with less thought as to whether the dependency was actually needed. This can bring in a lot of complexity fast to your code base (e.g., managing versions of those dependencies, build time increases, bugs, etc.).

Impacts to your team and career

In addition to all the above considerations, there are some that aren’t as directly tangible.


Additional thoughts

If you don’t limit the number of your dependencies, you may end up getting consumed by them and all of the costs associated with bringing them in. I’ll admit, keeping all these costs in mind for each dependency is a lot. Instead, try and be critical about what you bring into your project, and avoid dependencies if you can.

After all of this, you may be saying to yourself, “Okay, but I still need this dependency. Now what?”. In an upcoming post, I’ll have some thoughts to share for the times where you do bring on a dependency. Spoiler, think it through and be intentional about the process of bringing on a dependency.

Also, here are a couple other resources on dependencies that may be of interest:


Thanks for reading. Feel free to reach out on Twitter — cheers!

rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora