Aug 16 2010


Hot Company Seeks Conductors for Serious Relationship

Come to Relevance and help our team build awesome software solutions for our partners. We are currently hiring for several Project Manager positions as part of our growing team. We aren’t looking simply for Scrum Masters, or (definitely not) Microsoft Project experts, or even 30 years of management experience. We are looking for people who can enable a team to accomplish great things and provide a bridge between our team and our partners, making sure our communication channels are as broadband as possible and that the details are taken care of.

You don’t have to be an expert programmer to tackle this position; you do have to understand the practices of agile software development and be able to relate to deeply technical people and domain experts and everyone in between. Your job will be to ensure that our partners’ priorities are reflected in the work we do, every day. You will be responsible for being where the buck stops on the quality of our work, and for ensuring the highest value output of the development process.

If this sounds like you, get in touch with us at We suggest having read through how we work beforehand. We’re looking for people who live in or are willing to relocate to the Research Triangle area of North Carolina. (Our home office is in Durham.) Barring that, we’re also exploring having people in and around Washington D.C., or who are willing to be in our Durham office 50% of the time.

Aug 02 2010


The Relevant Bits - 08/02/2010 Edition

Presenting this week's edition of "What We Did With our 20% Time." Lots of stuff to talk about from more awesome gem releases to getting closer to the official release of Clojure 1.2.

Jul 26 2010


The Relevant Bits

As Justin mentioned last week, here at Relevance we spend 20% of our time on non-billable activities. Here's a peek into some of the activities that went on at Relevance HQ this past week.

Jul 19 2010


Welcome to our new teammates

Its always a joy to extend a public welcome to our new team members. Today, I'd like to publicly introduce our three newest compadres:

Jared Pace: Jared came to us from Charlotte, NC where he worked for a startup. He dumped PHP for Ruby four years ago and hasn't looked back. Today he can be found shifting between front and backend development or working on the Ruby library PDFKit.

David Liebke: David is a developer and statistician, and the creator of Incanter, a Clojure-based data analysis and visualization environment. He has built systems in domains ranging from bioinformatics to intelligence analysis, and has a B.S. in cognitive science (UC San Diego), M.S. in applied mathematics and statistics (Georgetown), an M.B.A. (UC Irvine).

Alan Dipert: Alan comes from Rochester, NY, where he studied at RIT and cofounded Rochester's first hackerspace. He's passionate about the Web, Clojure, and is an active open source contributor and advocate.

We are very excited to be growing our team, and expanding the reach of our Clojure services as well. Welcome, guys!

Jul 18 2010


Investing in Ourselves

When we founded Relevance in 2003, when it was just the two of us in Stu's garage, we established a rule that we would dedicate 20% of the "normal work week" to open source development. As the years have passed, and Relevance has grown (22 and growing!), the details of how we implement "20% time" and what we spend it on has undergone some gradual shifts, but the core principle remains: our team and our customers benefit when we spend that time on non-billable activities.

Our current version is that we spend our 20% time on Fridays. That means no client standups, no billable time, no deadlines to meet. But we don't just focus on open source (though that is still a major component). Team members can write or patch open source code, perform charitable work (through code or otherwise), focus on personal growth, work on long-term projects for company betterment, and contribute to the community.

Even though we've been doing this for 7 years now, we've been quite lax about collecting what we've done in one place. With that in mind, here's what we've done the past couple of weeks:

Jun 15 2010


Rethinking PDF Creation in Ruby

Every now and then, a requirement will come up in a project, that will make me second guess my career choice as a programmer. It usually involves making me go through tedious exercises, never knowing if I'll end up where I want to be along the way.

This happened a couple of weeks ago when one of our projects called for generating PDF reports. The reports needed many stylized elements, layouts, and dynamic graphs. If you've ever generated PDFs in Ruby before, you know that it can be both tedious and difficult using the standard go-to PDF libraries out there. Let's face it, we're web developers. Coming from HTML+CSS-based layouts, writing Ruby code for that stuff is a major pain.

To give you an idea of how heavy it can get, here's an example taken from Prawn. The example was ironically called simple_table.rb.

  Prawn::Document.generate("simple_table.pdf") do 

  table([["foo", "bar " * 15, "baz"], 
         ["baz", "bar", "foo " * 15]], :cell_style => {:padding => 12}) do
    cells.borders = []

    # Use the row() and style() methods to select and style a row.
    style row(0), :border_width => 2, :borders => [:bottom]

    # The style method can take a block, allowing you to customize 
    # properties per-cell.
    style(columns(0..1)) { |cell| cell.borders |= [:right] }

  move_down 12

  table([%w[foo bar bazbaz], %w[baz bar foofoo]], 
        :cell_style => { :padding => 12 }, :width => bounds.width)


If you're scratching your head at this point, the code above generates a PDF with two simply styled tables. That's it. If you asked me to implement this in an app, I might have something half-way presentable in an hour. But, I could get a monkey, who just drank a whole bottle of scotch—don't ask about his drinking problem—to write two tables using HTML in less than 5 minutes.

A New Hope

Now some of you may be familiar with PrinceXML, which is a command line utility that will take HTML+CSS and give you back a beautiful PDF. It's even CSS2 compatible and passes the ACID2 test. Awesome. The only problem is that a single server license will set you back $3,800—which is prohibitively not awesome.

Being the open source zealots we are here at Relevance, we set out to find another solution. Tucked away in the internets, we stumbled across wkhtmltopdf. I know what you're thinking; awesome name, huh? wkhtmltopdf uses a WebKit rendering engine to make pretty PDFs out of HTML+CSS. Since it's leveraging WebKit, you get all the tasty CSS3 properties it supports. Ugly PDFs are suddenly a thing of the past.

Goodbye Prawn, Hello PDFKit

We were surprised that none of us had ever heard of wkhtmltopdf, considering how useful it is. When we looked for a Ruby library that leveraged it, we realized it didn't exist. Apparently not a whole lot of other people had heard of it either. That couldn't stand. A couple of open-source Fridays and several gallons of Mountain Dew later, we're excited to announce PDFKit, an open source library that makes working with wkhtmltopdf a snap.


Inline HTML+CSS => PDF

  kit ="<h1>Oh Hai!</h1>")
  kit.stylesheets << '/path/to/pdf.css'
  kit.to_pdf # inline PDF

HTML file => PDF

  html_file ='/path/to/html')
  kit =
  kit.to_pdf # inline PDF

Remote HTML => PDF

  kit ="")
  kit.to_pdf # inline PDF

What's the big deal?

If this hasn't sunk in yet, let's go over a quick list of wins this buys us:

  1. HTML+CSS - Assuming you're a web developer, there's a good chance that you already know HTML and can work with it efficiently.
  2. CSS3 - We get WebKit's CSS3 support for free. This means effects like drop shadows, rounded borders, transformations and others are super-easy. (Note: effects requiring blur radius do not work.)
  3. Testing - We have tools built into our normal workflow for testing HTML. You can even use Cucumber to drive the development of a PDF with PDFKit.

To give you an idea of how well this fits into our normal workflow here at Relevance, this is how we built out our PDF reports:

  1. Our designer mocked up a sample PDF and converted it to HTML+CSS.
  2. Using Cucumber to drive development, we created a controller action to generate this HTML view of the PDF. (It was just another URL in our app.)
  3. We added a screen-only stylesheet to the HTML that mimics the look of a PDF reader. This allowed us to get a feel of how it would look as a PDF.
  4. Using a bit of Rack Middleware that ships with PDFKit, we can get the PDF version of that web page by simply appending '.pdf' to the url.
  5. We're done. No crazy extra class to handle PDF rendering. No need to spend all day reading through docs to learn the obscure code and magic incantations required to generate your PDF.


  • PDF of - PDF rendered from
  • CSS3 Examples - Sample rendering of common CSS3 effects including border-radius, text-shadow, box-shadow, and border-image. Notice the lack of a blur radius on text-shadow and box-shadow.
  • Sample HTML page with PDF viewer CSS - Example of using a single HTML source to render both a screen version and a PDF version. Uses a media="screen" and media="all" to mark relevant CSS.
  • PDF generated from PDF viewer HTML - PDF generated from sample HTML above. You must tell PDFKit to only use print stylesheets in order to achieve this effect (, :print_media_type => true)).

Go Forth and PDF

I encourage you to take PDFKit for a spin, let us know what you think, and even submit some patches.

If you are pumped about the possibility of using PDFKit on a future project, then I've achieved my goal. If not, I'd ask you to think about what is missing, find out if it's already out there, and let us know how to make PDFKit even better.

May 10 2010


Relevance Open-door Bug Mash Friday May 14

This Friday, May 14, Relevance Inc. is hosting a local bug mash in preparation for the Rails 3 BugMash May 15 & 16 organized by RailsBridge. We tip our hats to this worthy cause and hope to set a modest bar for the participants over the weekend.

Dan Pickett, who is coordinating the Rails 3 BugMash, recently challenged users to give back to the platform that has provided so much win for so many. At Relevance we certainly hear that message. Rails supports a significant portion of our work. It has been and continues to be one of the most progressive and dynamic platforms for programmers today. On top of that, it is fundamentally open source and thrives in a community of mutual collaboration.

In this spirit, we at Relevance pledge to donate our entire Friday to kick-starting the mashing festivities. Those bugs we target will be crushed not for prizes or glory, but out of gratitude to the platform and community. We are eager to see the magic that Rails 3 will produce and we hope to do our part to make that release the best it can be. If you will be in the area this Friday please feel free to stop by our office where there will be food, fun, and lots and lots of coffee.

You can find us at:
200 North Mangum St., Suite 204
Durham, NC, 27701

For more information, please contact us via email at or by phone at 919-442-3030.

Mar 02 2010


Jasmine for JavaScript Testing: It's Screw.Unit++

I'm pretty excited about Pivotal's JavaScript testing framework, Jasmine. The same folks who brought us Screw.Unit have upped their game. You still get the RSpec-style JavaScript DSL that you know and love, but Jasmine's a bit leaner and meaner, has a more robust architecture under the hood, and is sporting several exciting new features. I'm making plans now to move the Relevance fork of Blue Ridge over to use Jasmine instead of Screw.Unit.

New Infrastructure: No DOM or jQuery

Screw.Unit's biggest weakness is that it uses jQuery to store all its data in the DOM. The tests its going to run, their before/after behaviors, and whether they passed or failed -- it's all stored as attributes on DOM objects. It was a clever hack and works well enough for in-browser tests, but it causes trouble for headless testing.

Here's why: env.js is our DOM simulator. It pretends to be a browser, modeling HTML as JavaScript DOM objects. It strives to be an idealized DOM, separate from any particular browser's implementation. This is a pretty ambitious goal, and env.js does a pretty good job of it.

However, jQuery exercises the hell out of the DOM, and it really pushes env.js' buttons. It has to, since jQuery's biggest job is to adapt itself to whatever browser is running it. It pokes and prods env.js to understand its capabilities, and every new version of jQuery adds new tests. So, just about every time a new version of jQuery is released, it exposes areas of the DOM that env.js hasn't yet implemented, sometimes causing it to crash.

This situation isn't ideal, but it's workable if only your tests that exercised a particular part of the DOM failed due to the jQuery/env.js interaction. However, we often see these problems right away, as jQuery tries to determine capabilities early, sometimes stopping Screw.Unit immediately. Zero tests run. That is unacceptable.

Jasmine (like JSpec) doesn't need the DOM when it's not testing the DOM. It doesn't need jQuery when it's not testing jQuery. Jasmine was designed from the ground-up to be as stand-alone as possible. The folks at Pivotal have listed that as one of their most important design goals.

Easy Install & In-Browser Testing: The Jasmine-ruby Gem

The Jasmine-ruby gem is a Ruby program that generates Jasmine test scaffolding and that can run a small Ruby webserver to serve up your HTML fixtures. My favorite part of this is how environment-independent it is. No matter whether you're writing a Ruby on Rails app, a PHP website, a jQuery plugin, or even a Clojure webapp, it's the same command to generate and run your specs in-browser.

Other New Features

  • Leaner DSL:

    • Only superficial differences.
    • No longer wraps the whole test suite in a "Screw.Unit()" function.
    • Replaced Screw.Unit's matchers with a more JavaScript-y, camelCase syntax.
  • Asynchronous Testing Support

    • Learning from QUnit and JsUnit, Jasmine added testing tools for timers.
    • Very important for testing visual jQuery plugins, animations, etc.
  • Spies

    • Built-in mocking & stubbing.
    • Built-in "did-it-call-my-method?" checks.
  • Officially Maintained

    • Screw.Unit is basically abandonware.
    • Jasmine, however, is seeing active support from Pivotal.


So, a familiar DSL, less worries about the DOM and jQuery compatibility, and nifty new features -- I'm pretty excited to be using Jasmine. So long Screw.Unit, and thanks for all the fish.

Feb 09 2010


Relevance Welcomes Three to the Fold

We are very pleased to announce three new additions to the Relevance team:

Chris Redinger: An Extreme, Test-Driven Software Developer, Christopher has been programming since the mid-90s, when he cut his teeth on Perl while working his way through college in Maine. After putting in his time in the dot-com world, with the stock option wallpaper to prove it, he made the jump to consulting. During that time he used the myriad of available Java based web frameworks and came to the conclusion that there must be a better way. That better way for him started with the "Agile Manifesto" and has led him to Relevance, Inc. At Relevance he continues to refine ideas such as those in "Getting Real" and the Lean Startup movement, and how best to apply these in the Ruby and Clojure ecosystems.

Shay Frendt: Shay Frendt brings a passion for both business and technology to the mix, having worked in the startup space as a designer, in international marketing as a translator, in the corporate world as a public sector tax consultant, and now as a developer and project manager here at Relevance. He hails from Atlanta, plays the drums, can be found snowboarding in the Winter, scuba diving in the Summer, and coding at all other times.

Kristoffer Singleton: Kristoffer hails from a business consulting, project management and professional software training background. He has worked with companies of all sizes to deliver over 10,000 hours of hands on training seminars at industry conferences and companies throughout the United States including engagements with Fortune 100 and Fortune Global 500 companies. Kristoffer is a veteran of the video game industry, hailing most recently from the enterprise middleware development space for PC and console games where he was a Director of development. Kristoffer holds undergraduate degrees in Marketing and Management, an MBA from the Duke University Fuqua School of Business, and a deeply rooted belief that Batman (R) would always beat Superman (TM) in a fight to the death.

Welcome, all of you!

Jan 26 2010


Interesting Happenings During Craftsman Swap

We took part this past week in a Craftsman Swap with our friends at Obtiva. We sent them Aaron Bedra, and they sent us Tyler Jennings. I won't speak for them directly; you can read more about each of their experiences at their blog. I do want to mention that, as part of the swap, Obtiva asked Aaron to take part in their relationship with Mediafly and work on an app for the Hope for Haiti concert that took place last Friday. In one day, the team Aaron was on developed and deployed an app to live stream the concert on the Palm Pre and Pixi. This is worth nothing for more than the obvious goodwill angle (anything to help out with the recovery from the immense tragedy in Haiti is worthwhile) but it also demonstrates the quality of the people at Obtiva that they would think to include Aaron in the team working with Mediafly. So thanks to Obtiva and Mediafly for having Aaron take part, and thanks to George Clooney for coming up with the event in the first place. Don't forget to donate to the Red Cross whatever you can to help out.

Popular Tags