Dependencies: Convenience at what cost?

· 3 min read

Installing dependencies in our projects is easy and convenient. With just a few installation steps, you can solve complex problems that would take time to implement from scratch. But is it always a good investment?

Dependencies hide complexity from us, but that doesn’t mean we should ignore what comes in the package. On the contrary, understanding the full scope of each dependency becomes crucial, the devil is in the details.

And, it’s not just about the direct dependency you’re installing. What about its dependencies? And the dependencies of those dependencies? Who maintains each one of them? There’s a dangerous multiplier effect here, hidden in plain sight and often ignored.

The real problems

This web of direct/indirect dependencies creates several critical issues:

Security vulnerabilities: A critical security issue buried six levels deep in a dependency chain can compromise an entire application. The more dependencies a project has, the larger its attack surface becomes.

Maintenance overhead: Package updates are never isolated events. Dependencies conflict with each other regularly. Package A might require version 1.x of Package C, while Package B demands version 2.x, creating complex dependency resolution challenges that waste development and maintenance time.

Build bloat: You are carrying the baggage of each dependency and its dependencies, making the dependency tree larger than expected. Simple projects can end up with hundreds of megabytes of dependencies. Anyone familiar with those projects where node_modules is larger than the actual application code by a factor of 100?

What to do?

Smart dependency management requires a strategic approach:

  1. Question every new dependency. Does the functionality justify the overhead of another package? Could this be implemented in-house with reasonable effort?

  2. Use dependency analysis tools, review the source code and repository health of each new dependency you add to your project, checking:

    • How actively is it maintained?

    • How many open issues and pull requests?

    • What’s the test coverage?

    • How many contributors?

    • How many dependencies?

  3. Maintain regular and automated update schedules while carefully evaluating major version updates.

  4. Implement version locking through common tools like package-lock.json or yarn.lock, etc.

  5. Monitor dependency health continuously:

    • Set up automated security scanning

    • Watch for deprecated packages

    • Document dependencies that require special attention

Sustainability is hard but worth it

Optimizing for the short term is not enough. While it’s easy to bring in a dependency to fix an immediate problem, it might not be the best solution for your project’s long-term health. This isn’t an argument for zero-dependency projects, you shouldn’t always reinvent the wheel. The key is thoroughly evaluating the benefits and risks of new dependencies.

Dependency management is about exercising balance –a lost art in software engineering. It’s about making informed decisions that consider both immediate needs and long-term sustainability. After all, today’s quick fix shouldn’t become tomorrow’s maintenance nightmare.

New posts in your inbox. Unsubscribe anytime.