Welcome to Cykod. We are a fully-integrated, self-funded web-development startup located in Boston, MA.

When it's ok to Roll-your-own

Roll-your-own or Not-built-here syndrome is a mentality that rightly takes a fair amount of abuse. After all, with more than half a century of software development under our belt as a species do we really need yet another XYZ? Chances are it's been built before, and with a little bit of research you could find an existing workable alternative.

For a now-fairly-large ecosystem like Ruby/Rails, there's generally a plugin or a gem that gets close to what you need it to do, and with ruby's infinite flexbility, it's easy to make a couple of modifications and get what you need. Contrast `gem install XYZ` and `ri XYZ` with taking the time to really learn the problem domain of what your trying to solve, come up with a workable architecture and interface and implement.So we roll-our-own, throwing together some half-assed implementation that'll get the job done but will probably end being more trouble than it's worth.

It should be a no brainer - but often we take the latter path because we fear what we don't understand, and integrating a whole bunch of code, the pedigree of which isn't known is an understandly scary task. So we roll-our-own, throwing together some half-assed implementation that'll get the job done but will probably end being more trouble than it's worth.

That's not the time to RYO. If there's an available library that looks like it does the job, your time would be much better spent going through the code, online docs, tutorials and blog posts about it then jumping the gun and trying to write your own. However, don't necessarily just will-nilly throw the library into your project without giving it a solid once over, both at the API and at the code level.

We spend hours and hours coding, but when's the last time you took a couple of hours to read through the actual code of an auxiliary library that will perform an important function in your app? I'm getting better, but oftentimes the first time I look at the code is when something doesn't work right. It think that's a problem that should be fixed.

So, let's say you've looked at the library and it looks like a winner that's going to meet most of your needs. There's still now one more question that you need to ask yourself:

"Am I completely, overly and 100% happy with the interface that this library provides?"

You might be, but there are a number of example of circumstance where you could have a reason for not being completely thrilled. If the library provides more features than you need, you might not want your code to have to worry about overly complicated method calls. If the library provides too few features, and you need to call some other library's methods to get the output you need, you also have a reason for trepidation. Even something as basic as an unhappyness with the naming convention could cause some doubt - take fpdf for example - a 100% Ruby port of PHP's FPDF that keeps the same not-ruby-friendly name convention and a php method style.

Whatever it is, if you're not 100% happy with the interface or have some doubts about the library itself (is it being maintained, is it well written?), it's a great time to layer something between your code and the library. Technically it's called the Adapter pattern, but putting a layer of interfacing code is something that developers write all the time so you don't have feel like a pattern-snob.

Doing so actually a great way to figure out exactly what parts of the XYZ library you actually need and now much effort it is to make them work. If you're unit testing, you could even stub out calls to the adapter for the time being to make sure the interface you think you want to use makes sense.

(Brief interlude: I know what your thinking - "Who the $#@%@ is this guy, he titles his blog post 'When it's ok to RYO' and now is talking about the complete opposite - integrating libraries and the adapter pattern. What a jerk." That's ok, I've been called worse)

As we all know, change happens. Invariably something will pop up that make the XYZ library less of a perfect match than it used to be.

Just bear with me for one more second. Let's say you've got the XYZ library integrated behind a nice clean interface and your project is chugging along for a couple months. As we all know, change happens. Invariably something will pop up that make the XYZ library less of a perfect match than it used to be. Maybe the project is getting more advanced and you need to do more than the library was intended for. Maybe your realize that you don't need full XYZ support, just X+Z and the library is bloating your codebase for no reason.

Whatever the reason. Now's the time to RYO.

What's changed from way back when you originally need the functionality implemented in the XZY library? Well, three things:

  1. You know more about the XYZ problem domain - being forced to examine different options and actually integrate the library forced you to learn about it.
  2. You know a lot more about your application's needs for XYZ's functionality, not just from the requirements but from actual use.
  3. You having a working implementation of XYZ and have an idea of what they've done right and what they haven't. You are effectively building the second version of something without have had to build the first one.


For me, all three of these are big wins. We've now done this a number of times inside of Webiva. The rails file_column plugin is a great example - it was easy to get installed and working, but a couple of years down the road we need both less and more functionality and it wasn't being maintained. Luckily, since the Webiva codebase didn't have file_column's everywhere but instead had abstracted them in the DomainFile class - changing out that plugin for some custom code ended up not being too big of a deal. Authorization is another example - we used a great authorization plugin that we determined did a lot more than we needed, and a couple years down the line were able to easily extract the core functions we needed and roll-our-own very simply with a nice clean syntax (the main class SiteAuthorizationEngine clocks in under 200 loc)

Now sometimes the right library just isn't out there and you don't have a choice, but for the other 95% of the time, it's worth taking a look at the library that fulfills 96% of your requirements and writing the other 4% than the other way around. After all, you can always come back and write those 96% later on and you'll have whole lot of a better idea of what you're doing. 

Posted Friday, Jan 08 2010 09:15 AM by Pascal Rettig | Development

Leave a Comment

Display Name:


Your Email (Optional, not displayed):

Add a Comment: