The Dangers of Borrowing

Introduction

External dependencies, such as libraries, frameworks, and APIs, play a crucial role in software development. They help developers save time, reduce complexity, and leverage the work of others. However, it is essential to recognize the potential long-term drawbacks of relying too heavily on external dependencies. In this blog post, we will examine these drawbacks using my experience in systems development, project management, and cost-benefit analysis. We will also provide examples to illustrate both the benefits and the pitfalls of using external dependencies.

Increased Complexity and Maintenance Overhead

While external dependencies can reduce complexity in the short term, they can also introduce hidden complexity over time. Dependencies can have their own dependencies, leading to a tangled web of interconnected libraries that can be difficult to manage. As these dependencies evolve, developers may need to spend considerable time updating, debugging, and maintaining compatibility, which can offset the initial benefits of using external libraries.

A developer leverages a popular open-source library to implement
authentication and authorization in a web application, reducing development time
by weeks. However, as the library evolves and introduces breaking changes, the
developer must spend significant time updating and testing the application to
ensure compatibility.

Loss of Control and Flexibility

By relying on external dependencies, developers cede a degree of control over the functionality, performance, and security of their applications. When a dependency’s behavior changes or a critical bug is discovered, developers are often at the mercy of the library maintainers to provide a timely fix. This loss of control can impede a project’s progress and, in some cases, even put the entire application at risk.

A team uses a well-known JavaScript framework for building a
single-page application, significantly reducing the initial development time.
However, when the framework releases a major update that changes its core
functionality, the team faces increased development time as they must adapt
their application to the new version or risk being left behind with an outdated
and potentially insecure dependency.

Vendor Lock-In

When using proprietary libraries, frameworks, or APIs, developers may become locked into a particular vendor or technology. This can limit flexibility and make it challenging to switch to alternative solutions in the future. Vendor lock-in can result in increased costs, reduced innovation, and difficulty adapting to changing business requirements.

A mobile app development team decides to use a proprietary
 mobile app development platform that promises rapid development and easy
 deployment. As their app becomes successful, they realize that the platform's
 limitations and pricing model hinder their ability to scale and innovate. The
 team faces a costly and time-consuming migration to a more flexible,
 open-source alternative.

Security Risks

External dependencies can introduce security vulnerabilities into an application. When a dependency has a security flaw, it can expose the entire system to attack. Developers must closely monitor and manage their dependencies to mitigate these risks, which can be time-consuming and resource-intensive. Moreover, the larger the dependency chain, the greater the potential attack surface.

A widely-used open-source library suffers a major security vulnerability,
affecting thousands of projects that rely on it, including a popular content
management system. Websites using the affected CMS are exposed to potential
attacks until the developers can apply the necessary patches, resulting in lost
time and potential revenue.

Licensing and Compliance Challenges

Various licenses accompany different libraries and frameworks, presenting legal and compliance considerations for projects. Developers must exercise diligence in comprehending and adhering to the licensing stipulations of each dependency. Failure to comply with these requirements may lead to legal disputes, financial penalties, and damage to reputation.

A software company incorporates a library with a restrictive license
into their commercial product without appropriately abiding by the license
conditions. Consequently, they face an expensive lawsuit and unfavorable
publicity, compelling them to reevaluate their dependency choices and ensure
future compliance.

Performance Issues

The reliance on external dependencies can sometimes lead to performance bottlenecks, particularly when a library or framework is not optimized for a specific use case. These dependencies may include unnecessary features or code that can slow down an application or consume excessive resources. As a result, developers may find that a custom solution tailored to the project’s requirements could offer better performance than an off-the-shelf dependency.

A development team integrates a feature-rich library for data processing in
their application, aiming to expedite the development process. However, they
later discover that the library is not optimized for their specific data
handling needs and contributes to performance degradation. The team must then
invest additional time in optimizing the library or building a custom solution
to address the performance concerns.

Cost-Benefit Analysis

When considering the use of external dependencies, it’s crucial to conduct a thorough cost-benefit analysis to weigh the short-term advantages against the long-term drawbacks. Dependencies can provide rapid development, access to a wealth of pre-built functionality, and the opportunity to leverage the expertise of the broader development community. However, they can also introduce maintenance overhead, security risks, and other challenges over time.

To perform a cost-benefit analysis, developers should evaluate each dependency based on the following factors:

Stability: Assess the likelihood of the dependency undergoing significant changes or becoming obsolete. Maturity: Consider whether the dependency has a proven track record and is widely adopted by the development community. Community support: Determine the level of ongoing support and updates provided by the dependency’s maintainers and the broader community. Licensing: Ensure that the dependency’s license is compatible with the project’s licensing requirements and legal obligations. Security: Evaluate the potential security risks associated with the dependency, including known vulnerabilities and the maintainers’ responsiveness to addressing security issues. Performance: Assess whether the dependency is optimized for the project’s specific use case and whether it may introduce performance bottlenecks. By carefully examining these factors, developers can make informed decisions about whether to integrate an external dependency or invest in building a custom solution tailored to the project’s unique requirements. This analysis will help minimize potential risks and ensure that the project remains flexible, maintainable, and secure in the long run.

Conclusion

External dependencies offer numerous benefits in software development, including time savings, reduced complexity, and access to a wealth of pre-built functionality. However, it’s crucial for developers to carefully consider the long-term drawbacks and potential risks associated with these dependencies. By conducting a thorough cost-benefit analysis and evaluating factors such as stability, maturity, community support, licensing, security, and performance, developers can make informed decisions about whether to integrate an external dependency or invest in a custom solution tailored to the project’s unique needs. Ultimately, striking the right balance between leveraging external dependencies and maintaining control over critical aspects of a project will help ensure its long-term success, flexibility, and security.