"Not Invented Here" Versus Developer Sanity
prog21.dadgum.com
prog21.dadgum.com
There's a node package called "request" [1] that's a very, very popular third-party library to simplify HTTP requests. If you look at the code, though, it's really, really nasty - the whole thing is filled with global state. After I spent 6 hours in one day debugging issues in the library and filing bugs (some of which included things such as "if you try to set a querystring parameter, request can no longer follow redirects"), we decided that enough was enough and we rewrote it from scratch [2].
I think that rewriting it took us about as much time as we spent debugging it, but we were left with a project that's a drop-in replacement (as long as you're not using any of the advanced features) and has a codebase that's 1/10th (!!!) as many lines of code while implementing near 80% of its features.
There is one improvement I'd make. Your story here (spent hours debugging and filing bugs; spending the same amount of time rewriting got you further) is the most convincing reason to me. I'd document this in your comparison!
Edit: replace failed attempt at italics...
* Half joking.
Request has a lot of extra code to deal with the global state. It's written as one giant class that sets all of its properties on itself (e.g. this.method = options.method, etc., etc., followed by "http.request this"). Further, when it handles HTTP redirects, rather than instantiate a new instance of itself or something it just calls its init method a second time and has to make sure that it resets all of its properties to their default state (e.g. this.method = 'GET'). This is where most of the bugs come in, as well as most of the bloat.
In contrast, our's is a method that calls itself again with new options based on the context when it needs to handle HTTP redirects so we don't need to worry about that sort of stuff.
*I'm well known among my colleagues for writing way too much from scratch