Avoiding the Hazards of Dependencies - Part 1

Press Pause Before `pod install`

Avoiding the Hazards of Dependencies - Part 1

Press Pause Before `pod install`


About the author

Chris Griffith has been a game developer for over 19 years and a mobile developer since 2010. He’s produced dozens of apps and games for brands like Match.com, LEGO, Microsoft, Kraft, Anheuser-Busch and PepsiCo.

Chris has been a member of the PullRequest network since April 2018.

Be sure to check out other great work from Chris:


images/avoiding-the-hazards-of-dependencies.jpg

Important caveat: if your mobile app makes use of 3rd-party libraries, you’re in good company. Most do. They boost productivity and prevent a thousand reinventions of the wheel. As developers, we’re able to produce great products thanks in part to the thousands of amazing libraries others have published. When used responsibly, we’re standing on the shoulders of giants.

But this article I want to discuss why, as software developers, relying on others to make our software should still give us pause. While this is written from a mobile app developer’s perspective, the general questions raised are applicable to most engineering platforms.

A Tale of Two Crashes

My team and I produce mobile games. Our games rely in part on ads for monetization, like most in the industry. Ads are served by many different providers, all of which require the installation of their proprietary SDKs in our games. Most of them are closed-source, meaning they’re a “black box” and their inner-workings are not visible to us. More on that in a bit.

May 6, 2020

We got reports via Crashlytics that our iOS apps were all crashing on launch. Turns out, we were not the only ones. It seemed like the whole app ecosystem had been brought to its knees by a single SDK: Facebook’s. Luckily, Facebook is well-prepared for such an incident and has a system of kill switches designed to disable production features if they cause a problem. They were able to solve the issue without deploying a new SDK. All the affected apps just started working again.

July 10, 2020

It happened again. This time there was less panic, and Facebook addressed the problem swiftly. I noted the tenor of the reporting on it was less anger and fear as in May, but more of an eye roll and a “here we go, again” attitude.

In both instances, app publishes were fortunate that party responsible for resolving was a billion-dollar company with thousands of great developers who were well-prepared to respond to the crisis. Imagine a scenario where the provider of an SDK wasn’t as prepared, the fix required a new SDK along with new app submissions to the store and a full force-upgrade cycle. Popular apps could have been offline for days or upwards of a week while the problem was being resolved. A seemingly small problem at scale could disrupt the revenue generated by an entire industry vertical . This is the risk we as developers take when we integrate 3rd-party software into our apps.

Some of you reading this may see this as overly alarmist. I’m not calling for every company that makes software to adopt Not Invented Here as their modus operandi. Not only has that ship long sailed, but it would also slow down development efforts to a crawl. Mobile game publishers would instead lose the many benefit of having a battle-tested, standardized solutions for repetitive problems. Instead, what I’d like to propose is a more modest thought exercise.

Press Pause Before pod install

Cocoapods/Carthage/SPM on iOS and Gradle on Android have made it incredibly easy to integrate open or closed source software into our projects. Just add a single line dependency, rebuild, and you’ve got new functionality waiting to be tapped. This has rapidly sped up small development teams' ability to stand up apps quickly and stably. It’s really quite amazing. However, I’ve managed mobile projects with 30+ external dependencies and seen how poorly things can go. For instance, when a major OS update occurs that breaks an old API or deprecates functionality it can trigger a cascade of warnings and errors that need urgent, and unexpected, attention. What seemed like a free lunch upfront can end up being debt you never finish paying off. If a dependency is open source, there’s the very real possibility the maintainer(s) will someday abandon it. Suddenly you’ve involuntarily “adopted” the software as your own, or you do the work to extract it and replace it with something else. These are not trivial costs, but they are rarely tabulated because the barrier to entry feels like, well, nothing.

So here’s my proposal. Before a decision is made to add any dependency to your mobile project, ask (and answer, either for yourself or collectively as a team) these questions.

1. What do we need this software for?

Sometimes the answer to this is pretty obvious. In the case of Facebook, the only viable way to integrate with the services they offer is to use their SDK. As a plus, it is mostly open-source, which can help tremendously in tracking down the root of problems. What about libraries intended to save time by not re-inventing tech? Alamofire on iOS comes to mind. It’s a long-standing package for handling client/server communication. It’s very powerful and written by outstanding engineers, but it’s also immense, complex, and prescriptive in its uses. Because of improvements Apple has made to their networking components over time, a simple network stack (that’s very easy to understand from end to end) can be written in a few days. If the argument for adopting Alamofire is to save time, take a close examination if it’s the best choice and if it will. If the case is, “No one wants to write a network stack,” my question would be: “Why?” You’re going to be on the hook for anything that goes wrong with it, regardless of who wrote it. In some cases it may make sense to, and I’d personally rather have to debug my own code than someone else’s. NOTE: Alamofire is a great library and used for the sake of example here, the point here is to ask these questions.

2. How much effort is saved by incorporating the software?

If the software is the Facebook SDK, the answer is more or less infinite, and this question can be skipped. But if it’s a library that performs some convenience UI styling, it’s a question worth asking. It can be tempting to incorporate solutions that promise to save us any amount of time. However, I would argue there is also value in time spent learning. Maybe you have a junior developer on your team who still needs to learn a lot of the nuances of UIKit. Instead of incorporating an opaque (admit it: even if it’s open-source, no one is going and reading the code) tool to do some menial task, assign this person to implement it instead. Now you’re both owning the solution and deepening your team’s understanding of the platform.

3. What are the license terms of the software?

This is often overlooked in an eagerness to solve a problem, but it’s very important. Depending on what industry your company is in, there may be rules about which levels of license you can use. For some, MIT and Apache are the only viable licenses, while for others GNU might be fine. Even if you don’t understand all the legalese, you need to know the implications. Open source vs closed source also falls under this consideration. If a library is open-source, you can better evaluate what it’s doing and determine additional risks. You could even decide to contribute to its development as part of your efforts. If the software is a closed black box, you will likely be at the mercy of another company to fix problems that arise. Also, if it’s closed source, know what the terms and conditions are about your user’s data and privacy before incorporating it. If it turns out the company is doing something unfavorable, like collecting and selling your users' email addresses, you may find yourself bound with legal complications. Also, software licenses can change over time with new versions. Be sure to keep up with them and make sure your usage is compliant.

4. What do we do if this software suddenly becomes unavailable?

I’ve worked on multiple projects where dependencies, both small and large, have gone extinct. One was a library for making the iOS address book (a notoriously kludgy framework) easier to work with. It had a single author on GitHub who had a day job and abandoned it. I had to make some changes myself, and while it probably still took me less time than if I’d written it myself, it did put me behind schedule. Another was when Facebook bought (and later shut down) Parse. That was a platform many apps depended on, and all the hours developers saved by using it suddenly came rushing back in the form of the time spent migrating from it or choosing to shutter their apps. This isn’t about predicting the future - some percentage of software will inevitably become obsolete. It doesn’t even have to be a technical issue; a license change could suddenly mean using the code in your product is now in violation and has to remove it or face legal action.

5. What do we do if this software breaks?

Similar in theme to #4, this brings us back to the crashes from May and July. In those instances, the world had to pretty much stand there and wait for Facebook to fix everything (and to their merit, they did very quickly). But what happens if it’s not a company with the market clout, capitalization, and size of Facebook? It’s not a pretty picture to imagine. No one wants to be up at 3 AM desperately trying to extract a dependency and replace it with a different dependency or something bespoke.

The bottom line is that all of your software’s stakeholders need to be aware of the possible risks and long-term costs involved with any external software incorporated as part of the larger the product. The ultimate answer to all of these may be, “I don’t care,” or, “It’s worth it.” But in my opinion, they are questions that should always be asked.

Put another way, when thinking about an external piece of software, imagine what you’re actually doing is contracting the author to work for your company. Except that unlike an employee or normal contractor, you don’t have any real influence over the decisions they make or direction they go, or if they just give up and walk away. Tech companies usually have fairly rigorous standards when it comes to hiring new team members, often heavily vetting them beforehand for competence and skills. How often does a version of that happen for the software we choose to adopt? I’m guessing pretty seldom, which is where the problem lies. We should be vetting 3rd-party libraries like potential employees - is this “someone” we want working for our company for 2 years? 5? 10?

Where to go next

If this article has raised any anxieties about the 3rd-party software incorporated into your apps, please accept my sincerest apologies, it’s not meant to. My goal is to raise awareness of the possible consequences that I’ve seen surface in many of my own projects and in others'.

In a follow-up article, we’ll discuss some ways of mitigating the risks introduced by 3rd-party libraries. If you’re taking on risks, it’s good to hedge your bets and have a plan.


Be sure to check out other great work from Chris:


About PullRequest

HackerOne PullRequest is a platform for code review, built for teams of all sizes. We have a network of expert engineers enhanced by AI, to help you ship secure code, faster.

Learn more about PullRequest

Chris Griffith headshot
by Chris Griffith

July 28, 2020