Open source frameworks are great and I encourage you to use them when appropriate. However, there is a such a thing as too much of a good thing. There is a point where your project becomes more a stitched together Frankenstein’s monster than an elegant well crafted piece of software. Of course this doesn’t just happen by magical fairies adding dependencies; there are warning signs that you may be in a bad spot with your use of open-source before it becomes a real issue.
In no way do intend to criticize the proper use of open-source software. In fact, I still use ASI and similar plumbing tools in many of my projects. The trick is that I always have an exit strategy; for example, in the case of ASI, if the time ever came to switch I’d probably move over to the more modern AFNetworking. On the web side of life, I tend to use JQuery fairly heavily but always keep an eye out for smaller (possibly leaner) alternatives.
If you don’t have an exit strategy, things can get very bad very quickly for you if the project you rely on is either canceled or stops being updated and becomes too out of date to easily use in your domain. But why? Why do we do this ourselves? Why do we keep inheriting projects with huge and in many cases unneeded dependencies? Aren’t there warnings? There are warning signs and I’ve seen some common patterns in the (often flawed) logic of some of the worst offenders.
Pre 1.0: Lately, I’ve been seeing a disturbing quantity of pre 1.0 software being used in production. This is madness. Pure madness. If the creators / maintainers of project don’t think it is production ready, then you simply should not be using it in production. If you do and run into issues, you pretty much deserve what you get.
Fear: This has to be the most common reason that I see developers take huge dependencies that are more than a little questionable. Many developer fear technology that they don’t understand or don’t have experience with and attempt to abstract it away with clunky frameworks. This is pretty common in the Apple space (iOS / Mac OS X), since many developers fear Core Data and go through some pretty silly hoops to avoid using it directly. These ‘hoops’ tend to be large frameworks that your entire project ends of being written around, making removing them later a costly and painful endeavour. In the example of Core Data, the irony is that Core Data is itself an abstraction designed to simplify working with datastores.
Closed Mindedness: This is another area where the Core Data example comes into play. There are a number of newer iOS developers who feel that Core Data should be just like Rails / Activerecord, so they turn to dubious frameworks to get that. Again, this is particularly questionable since Core Data already supplies a style of object relational mapping and is in itself an abstraction. Not to pick on Rails folks too much, but I’ve been seeing a scary number of ‘Rails-like’ frameworks popping up. The issue with this is that Rails already exists and does a good job solving the problems it was designed to solve, however, it was not designed to solve all problems; other approaches and tools would be more appropriate for other problems. Of course this issue can go all the way down to the language level. For example, I’m often forced to work with Objective-C that has been written as though it were Java by people who seem to have no understanding of the messaging paradigm in Objective-C and are more than happy to force Java concepts / practices on the language whether they fit or not.
Budget: This is the most understandable reason for taking on large dependencies. Today’s project managers are severely constrained in terms of budget available per project and there is a real need to cut costs. I have a lot of sympathy for this one. However, you should remember that there is more to a project’s cost than just the initial development cost; there is also maintanence. If you do take one of these large dependencies make sure you have a roadmap for you will maintain and grow with the dependency itself; there is nothing worse than building an app on framework A and realising a year later that it needs to be substantially rewritten in framework B to adapt to your changing needs or scale.