A quick note on dependencies in Ruby on Rails projects

Manfred Stienstra

In response to the latest Ruby on Rails security announcement we upgraded all of our clients’ Rails projects in less than 36 hours. On average it took around 30 minutes to upgrade a project from checkout to deployment.

On Twitter we mentioned our ‘minimal dependency policy’ in projects as being one of the reasons we could move so quickly. We got some questions about what that means exactly.

First off it’s important to note that this policy is not something we’ve printed on a sign and hung on the wall. It’s just one of practices that’s part of the culture at Fingertips.

It’s surprisingly easy to follow; when you work on a new feature and want to add a dependency you ask yourself if you really need it.

Please note that in this context, a dependency can be an external library, a piece of code you copy from another project into `lib/`, or even requiring something from the standard library.

  1. Second guess yourself. Do I really, really need this?

  2. Will this solve my problem? Does the library I want to use fit my problem really well or am I better off writing 20 lines of code myself? For example: pull in Devise or use HTTP basic authentication.

  3. Should I use this particular library? Sometimes using another library allows you to drop one you were using for another feature. For example: use OpenSSL for both certificate signing and random token generation and drop Mongoid::Token.

  4. Check if the new dependency has dependencies itself and weigh it against the benefit of using it. For example: use Net/HTTP for that one HTTP call instead of depending on HTTParty.

Minimal dependency is not just about the number of libraries you use, but also about the total amount of code you pull into your project. Less code means less bugs.

It will also give you less trouble with interdependencies when you try to upgrade. For example: Rails needs Rack 1.4, but Resque requires Sinatra and Sinatra doesn’t run on anything newer than Rack 1.3.

Finally, less dependencies makes long-term maintenance easier because there is less that can go wrong when it’s time to upgrade to a new major version of Rails. For example: if you depend on will_paginate in your Rails 2.3 project, you’ll need to use a newer version for Rails 3.2 which has a slightly different API.