Disclaimer: Just a heads up, while we’re diving into ways to tackle the problem of dependency depreciation, there’s no one-size-fits-all solution here. It’s a bit of a wild ride dealing with supply chain security and those pesky deprecated dependencies, so don’t expect a quick fix!

The issue of using deprecated dependencies has persisted for quite some time, and it’s gaining increased attention. Many projects continue to incorporate deprecated dependencies.

I was inspired to write this blog after coming across a LinkedIn post by Rory McCune and several other posts over the past few weeks.

I agree with what Rory has to say here!

I agree with what Rory has to say here!

So, I decided to share my perspective on how we can mitigate security risks and effectively navigate the challenges of dependency management. I decided to use the npm ecosystem as an example here because, well, it’s what I’m dealing with right now.

Before we dive deep, let’s set some context on what are the challenges associated with these deprecated dependencies?

When the same question was posed to ChatGPT, it eloquently addressed the concerns.

What's the problem with deprecated dependencies?
Deprecated dependencies can pose several problems for software development projects:
  1. Security Vulnerabilities: Deprecated dependencies may contain known security vulnerabilities that are no longer patched or updated. This can leave your project vulnerable to potential exploits.
  2. Compatibility Issues: Deprecated dependencies may not be compatible with newer versions of other libraries or frameworks, leading to conflicts and issues that can disrupt your project's functionality.
  3. Lack of Maintenance: Deprecated dependencies are typically no longer actively maintained or updated by their developers. This can lead to problems such as unaddressed bugs or performance issues.
  4. Inefficient Performance: Deprecated dependencies may not take advantage of the latest performance optimizations, potentially slowing down your project.
  5. Breaking Changes: Upgrading other parts of your project or platform may reveal breaking changes or incompatibilities with deprecated dependencies, requiring additional development work to resolve.
  6. Reduced Community Support: As dependencies become deprecated, their communities may shrink, making it more challenging to find support or resources to address issues or questions.
  7. Technical Debt: Relying on deprecated dependencies can accumulate technical debt in your project, making it more difficult and costly to maintain in the long run.
To mitigate these problems, it's essential to regularly assess and update dependencies, following best practices for dependency management in your development projects.

TL;DR - Deprecated dependencies can cause problems such as,

  • Security Vulnerabilities
  • Compatibility Issues
  • Lack of Maintenance
  • Inefficient Performance
  • Breaking Changes
  • Reduced Community Support
  • Technical Debt

So, what’s the plan, you might wonder? Well, that’s exactly what we’ll dive into in the next sections.

Getting Visibility On Deprecated Dependencies

When we execute npm install, it installs all the required dependencies for the project to function. However, this process also generates warnings related to these dependencies. The issue is that these warnings encompass a wide range of issues (vulnerability warning, peer dependency warning, missing script warning, unmet dependency warning, deprecation warning, etc.), and they often tend to be disregarded simply because they are categorized as ‘warnings’.

Alarm fatigue or alert fatigue describes how busy workers become desensitized to safety alerts, and as a result ignore or fail to respond appropriately to such warnings.

…for more details read here.

The approach to tackle this is to devise a carefully tailored method to draw attention to these issues and provide context about the dependencies. The cool part is that npm, by default, offers the necessary tools; all we need to do is adeptly shape and present it to the users in a manner that highlights the problem effectively.

So, what information do we need to give the consumer?

  • What are the deprecated dependencies?
  • Is it a direct or transitive dependency?
  • Context of the dependencies?

The below script does all of that -

#!/bin/sh

npm install

# Define the jq query and package-lock.json file
JQ_QUERY='.packages | to_entries[] | select(.value.deprecated != null) | "\(.key)@\(.value.version)" | sub("^node_modules/"; "")'
PACKAGE_LOCK_FILE="package-lock.json"

# Run the jq query to get the list of deprecated dependencies
DEPRECATED_DEPENDENCIES=$(jq -r "$JQ_QUERY" "$PACKAGE_LOCK_FILE")
DEPRECATED_DEPENDENCIES_STR=$(echo "$DEPRECATED_DEPENDENCIES" | awk 'ORS=" "')

# Check if DEPRECATED_DEPENDENCIES is not empty before running the loop
if [ -n "$DEPRECATED_DEPENDENCIES" ]; then
  echo "$DEPRECATED_DEPENDENCIES" | while IFS= read -r DEPENDENCY; do
    npm view $DEPENDENCY
    npm list --depth 1000 $DEPENDENCY
  done
  echo "----------------------\n"

  echo "Overall Depreacted Dependencies (Dependency Tree): "
  echo $DEPRECATED_DEPENDENCIES_STR | xargs npm list --depth 1000

  rm -rf node_modules/ package-lock.json
else
  echo "No deprecated dependencies found ✨ Yay! 👏"
fi

and this gives output like this -

  1. For the direct dependency - Direct Dependency Depreciation Screenshot
  2. For transitive dependency - Transitive Dependency Depreciation Screenshot
  3. Overall Summary (Depedency Tree of Deprecated Dependency) - Dependency Depreciation Tree Screenshot

Now, let’s delve into the implementation aspect.

One approach that comes to mind is to incorporate a script that runs during each deployment within your CI/CD pipeline. This script would then send a detailed report to users through accessible platforms like Slack or Discord. Users can conveniently review the report and take necessary actions.

If you’re feeling daring, you can even take it to the next level by potentially halting the pipeline when deprecated dependencies are detected. However, I’d like to emphasize that this more stringent approach might not always be the best fit, and its suitability largely depends on your specific use case.

Getting Visibility on Unmaintained Dependencies

Another valuable approach is to leverage open-source tools like vet , which can assist you in identifying projects and dependencies that are no longer actively maintained. This insight can be incredibly informative and help you make well-informed decisions about your dependencies.

Vet OSS Maintained Filter

Possible Action Items

The actionable steps may vary depending on the situation, but in an ideal scenario, consider the following options:

  • Remove the Deprecated Dependency: When feasible, it’s advisable to remove the deprecated dependency from your project to eliminate potential issues.
  • Fork and Maintain: In some cases, forking the dependency and taking responsibility for its maintenance can be a viable solution, especially if it’s critical to your project’s functionality.

But let’s face it, we’re not in an ideal world.

Ah! bummer!

So, what should we do?

In the face of ongoing challenges posed by deprecated dependencies in software development, there are practical steps we can take. By adopting a more mindful approach, engaging with the community, and utilizing automated tools, we can better address these issues. Regular audits, occasional forking, and continuous learning can help us navigate this landscape more effectively. With a pragmatic outlook and adaptability, we can work towards a future where deprecated dependencies are managed effectively, allowing our projects to thrive with confidence.

As I wrap up this blog, I’d like to leave you with a thought from my presentation on Dependency Hell, courtesy of @anantshri: ‘We will not be talking about creating Dependency Heaven, but will talk about how to be the Lucifer in the hell.’

See’ya! Until next time!