This hilarious article with a click-bait title caught my attention, recently: I Peeked Into My Node_Modules Directory And You Won’t Believe What Happened Next.
Dependency Hell Isn’t New
Dependency hell is a term that made it into Wikipedia. It defines it as such:
Dependency hell is a colloquial term for the frustration of some software users who have installed software packages, which have dependencies on specific versions of other software packages.
The big problem in dependency hell is the fact that small libraries pull in additional dependencies on which they rely in order to avoid too much code duplication. For instance, check out who is using Guava 18.0.
You’ll find libraries like:
- com.fasterxml.jackson.core » jackson-databind.
- org.springframework » spring-context-support.
- org.reflections » reflections.
- org.joda » joda-convert.
- … 2,000 more.
Now, let’s assume you’re still using Guava 15.0 in your application. You want to upgrade Spring. Will your application still work? Is that upgrade binary compatible? Will Spring guarantee this to you, or are you on your own? Now, what if Spring also uses Joda Time, which in turn also uses Guava? Does this even work? Conversely, can Guava ever depend on Joda Time, or will a circular Maven Central dependency cause all singularities to collapse into one huge black hole?
Truth Is: You Don’t Need the Dependency
… and by you, I don’t mean the end user who writes complex enterprise applications with Guava (or whatever). You need it. But YOU, dear library developer. You certainly don’t need any dependency.
- They have some nice StringUtils, which we like to use.
- Their license is also ASL 2.0, which is compatible with jOOQ’s license.
But instead of hardwiring a jOOQ 3.x to commons-lang 2.x dependency, we opted for internalizing one of their classes and only parts of it, repackaging it as
org.jooq.tools.StringUtils. Essentially, we needed things like:
- leftPad() (hello node developers)
And some more. That certainly doesn’t justify pulling in the entire dependency, does it? Because while it wouldn’t matter to us, it would matter to our thousands of users, who might prefer to use an older or newer version of commons-lang. And that’s just the beginning. What if commons-lang had transitive dependencies? Etc.
Please, Library Developers, Avoid Dependencies
So, please, dear library developers. Please avoid adding dependencies to your libraries. The only things you should depend on are:
- The JDK.
- Some API governed by a JSR (e.g. JPA).
That’s it. We can all start writing better software and stop downloading the whole internet if YOU, the library developers, start being reasonable and stop being lazy.
Exceptions to the above rules:
- Framework and platform vendors (e.g. Spring, Java EE) are excluded. They define the whole platform, i.e. they impose a set of well-documented dependencies. If you’re using a framework/platform in your application, then you have to abide by the platform’s rules
That’s all. Small libraries like jOOQ must not have any dependency.