Three Talks

I’ve been busy this month speaking at HackSI, YUIConf, and Bayjax. The videos will be available soon, but you can check out the slides now:

My testing talks reveal what I’ve been working on for a few months: yo/tests, a commit-based test report for YUI that helps us ship quality releases. Compared to Jenkins’ build-based test silos and build-based CI dashboards, yo/tests actually lets engineers know what’s broken by organizing results around commits instead of build numbers and hiding flaky tests and infrastructure.

Commas for Developers

Brent Simmons pays attention to the details and gets right to the point:

If your writing — in tweets and especially on your blog and product pages — is full of misspellings and improper capitalization and other errors, I will lose trust in you and your product. If you’re careless with language, are you also careless with software development?

I make misspellings and other errors more often than I’d like. Everybody makes these mistakes. Yet, I think it’s important to put as much care into finding errors in language at least as much as finding errors in code.

(The crux of his post is something that I was instructed to avoid over and over again in middle school. I can relate.)

Sharding & IDs at Instagram (2012)

Back in 2012, Instagram Engineering wrote about sharding & IDs. I re-read it yesterday and this particular requirement for their ID generation system still stands out:

The system should introduce as few new ‘moving parts’ as possible—a large part of how we’ve been able to scale Instagram with very few engineers is by choosing simple, easy-to-understand solutions that we trust.

“Simple, easy-to-understand solutions that we trust.” Their solution skipped fancier alternatives for something that worked. Remember: you’re paid to write code that works.

Why mobile web apps are slow

Drew Crawford wrote a very long and well-cited article about why mobile web apps are slow.

Now I am going to warn you–this is a very freaking long article, weighing in at very nearly 10k words. That is by design. I have recently come out in favor of articles that are good over articles that are popular. This is my attempt at the former, and my attempt to practice what I have previously preached: that we should incentivize good, evidence-based, interesting discussion and discourage writing witty comments.

The article primarily discusses JavaScript performance. After reading Drew’s article, you’ll understand why JS usage on mobile has to be relatively light compared to what you can get away with on desktop.

I’d love to see more of this good discussion on non-JavaScript impediments to creating good mobile web apps.

Build Modules, Not Examples

I’ve been thinking out loud this afternoon about how modules make Node.js successful with @ekashida, YUI’s newest team member.

YUI is a powerful open-source library for developing web apps. Node and YUI both document their APIs very well. Unlike Node, we also have 250 examples to help people get started. Yet lots of people have trouble getting started anyway.

How do we make that easier?

We’re not the only web app library with this problem. Ember has received criticism around getting started and quickly responded with a roadmap to improve it. In their response, Tom Dale said:

Ember promises—and, we think, delivers—tremendous value. But ramping up to that point is not easy, and we received this feedback repeatedly and take it very seriously.

We get the same feedback for YUI. We also take it seriously and a fellow team member is working on better documentation. Ember’s action items include a Getting Started guide, a short screencast, live examples to run demo code, and other things. These are good and will help.

But then, I think about Node. Their official newbie documentation begins and ends with Hello World on their homepage. Node’s newbies do not get started with an example. They get started with npm.

Modules Are The Example

Node has effectively outsourced their examples to the community using npm.

You may be thinking: “Reid, modules are not examples. They are tools you use to build an example, or a real app.” Well, you’d be right. Node’s community has built enough modules to help people build apps they care about with a tiny learning curve. Instead of reading about code, these newbies are building something with a tool—the module—that lets them start building what they care about right away.

Few newcomers to Node.js use require("http") to build their first web app. If the barrier-to-entry was to understand the HTTP module, a lot of people would walk away. They don’t want to learn about that module, they want routing. View rendering. You know, a web app.

The example is Express. Newbies have a project in mind and it’s probably something that needs a router, view rendering, and middleware. Express delivers that. You don’t need to learn about Node yet, you learn Express.

Once you’re up and running, you have real code and real problems. Not theoretical problems in a narrative, but problems that are running on your computer. Problems getting in the way of building what you care about. That’s motivation.

Since you’ve already spent an hour getting the basics setup because the Express API was a lot easier to get started with, you’re now motivated to dig deeper into Node to find the next solution.

Building A Ramp, Not A Cliff

Understanding everything Node has to offer isn’t something you learn overnight. But that isn’t necessary. A lot of people have built modules on top of Node’s core that make all kinds of common problems easy. These modules are easy to download and use. Newbies are engaged immediately. Then, they’re are progressively lured into deeper water. The community grows.

If you need to learn a million things before you can get started, you’ll never start. If that’s your project’s learning curve, you’re presenting newbies with a cliff. Some people will climb it, some will seek climbing experts to get to the top. Some may have the patience to read a book about climbing, or watch a screencast featuring someone else climbing.

But most people want to get started today, so they’ll leave and find an alternative way to the top that’s easier to climb.

Node provides many ramps. They aren’t ramps you merely read about: they’re ramps you walk on, build on, get experience with, and get more complicated as you go up. It doesn’t fix every problem and some people will still be confused. But it works pretty well.

At YUI, I’ll be encouraging our team to focus on building example modules: the ramps to mastery. YUI is already modular, but that isn’t the same. I’m talking about bundling modules in YUI’s core into a fully-baked solution to a common problem. Other people on my team are hard at work on the first product, and now I know why I’m so excited: it’s a ramp.

Own Your Email

If you’re reading my blog, you might be a professional working in technology. You’re likely to care about your online identity, and if you do, your publishing and communications must happen from your own domain.

If you care about your online presence, you must own it. I do, and that’s why my email address has always been at my own domain, not the domain of any employer or webmail service.

You might think your address will be fine indefinitely, but if I used a webmail address from the best webmail provider at the time I broke away from my university address and formed my own identity, it would have ended in And that wasn’t very long ago.

Own Your Identity by Marco Arment

I’ve had email at my domain for many years, so I don’t face the headache some do with switching today. If your email ends with someone else’s domain, bite the bullet and make the switch. The best time may have been in the past, but the second best time is right now.


I’m currently trying out FastMail for hosting my email. I previously used Google Apps for Your Domain. Since late last year, that product has been focused on businesses. I’ve wanted to try the benefits of paid email (no ads) with a bring-your-own-domain service intended for individuals.

Here’s some factors that went into my decision to try FastMail:

Here’s what I don’t like, and why you shouldn’t switch:

  • I’ve had a couple spam messages come into my FastMail inbox, which rarely happens in GMail. You can train a personal Bayes filter over time, and tweak the spam score sensitivity, but I doubt it’ll be as good.
  • No 2-factor auth without expensive SMS messaging, but I don’t need this as much since I use 1Password.
  • Their documentation is pretty atrocious. They document everything but you’ll spend time digging for it.
  • Filters are not as easy to setup, but you get to edit the code behind them which is based on standard Sieve.

The good: Their website is fast. Gravatars are used in their website and I prefer its look-and-feel to GMail. If you don’t like it, you can run your own custom CSS and JavaScript to customize it.

We’ll see how this works out. If you decide to switch, read their migration instructions to get properly relocated from your current IMAP provider. Make sure you put SPF and DomainKeys into your DNS configuration while you’re changing MX records. The SPF record to set is v=spf1 -all (on TXT and SPF, if your DNS does both). The DomainKeys TXT record to set is on the “Virtual Domains” advanced settings screen once you sign in.

No matter what you choose, go forth and own your email. Even if my trial of FastMail goes south, they’re just a provider behind my own domain, and I can even go back to GMail. Switching providers is easy once your email is on your domain, so get to it.

Debugging Travis builds

Important Update December 19, 2013 — Travis infrastructure has changed since this post was written. This post remains unchanged for posterity; however, be aware that this setup no longer represents the current state of Travis.

Yeti uses Travis CI to the max by spawning lots of PhantomJS processes that are tested asynchronously. When tests start failing in Travis, but not anywhere else, debugging can be infuriating.

You can setup a Travis box locally to debug the problem. Trung Lê wrote about debugging with a local Travis VM in August 2012 but that post is outdated and didn’t work. You can expect sweeping changes to the Travis build infrastructure in the near future, so this blog post will also be outdated soon.

For now, we have a bug that needs fixing. Let’s setup a local Travis VM for Node.js debugging.

My assumptions about your computer

  1. Plenty of disk space
  2. OS X (but this should work with other systems, too)

Install Vagrant & VirtualBox

Visit the Vagrant website and the VirtualBox website for installers.

Download the jvm box

The jvm box is where Node.js builds run. Download (3.2 GB)

Prepare the jvm box

Import the VM box:

vagrant box add travis-jvm

Verify it’s there:

vagrant box list

Start the jvm box

Create a working directory to hold the Vagrantfile for the travis-jvm box.

mkdir boxes
cd boxes

Create the Vagrantfile and get the box ready to use:

vagrant init travis-jvm

The username for the VM is travis, so add this line to your Vagrantfile’s do-block:

config.ssh.username = "travis"

Start the VM:

vagrant up

Things should work nicely. (If not, read on.)

You can access the VM with this command:

vagrant ssh

You can now follow the steps of your Travis build and debug your problem.

If you have problems running vagrant ssh, you can try using a username and password for logging in instead with this command:

vagrant ssh -p -- -l travis

The password is travis.

More fancy debugging

The VM uses a NAT-only network. You may not be able to access it from your computer. For the problems I debug, I need to be able to access the the Node web server inside the VM from a browser on OS X.

This means you should setup a host-only network interface, in addition to the NAT-only interface.

Add this line to your Vagrantfile’s do-block: :hostonly, ""

This will setup a host-only network and give the IP address to the VM. (If you are on a network that uses already, change the IP subnet to something else, because it cannot conflict with another subnet your host computer is using.)

Reload the VM:

vagrant reload

You should be able to access the VM from the host at

Sometimes running vagrant up with a host-only network fails because of a bug in net-ssh and Vagrant with the message “Waiting for VM to boot. This can take a few minutes.” This bug is quite annoying, but a detailed workaround procedure that clears DHCP leases is available that’ll allow you to start the VM.


You can pause the VM with vagrant suspend and bring it back to life with vagrant resume. If you’d like to power off the VM, do so over SSH. If you can’t, vagrant halt will power it off.

If you want to start from a clean slate, you can destroy it with vagrant destroy. Re-creating a fresh VM is as easy as vagrant up.

You can learn more about these commands by reading the Vagrant teardown documentation.

Do not debug on

When you have a Travis-only problem, try creating a local environment as described above first. Don’t try to use the hosted Travis service to debug complicated failures. I have made this mistake many times:

  1. Noticed my build is failing in Travis.
  2. Make sure my own environments and clean installs do not fail. (The problem is sometimes here!)
  3. Create a branch named fix-travis-foo or something.
  4. Start making commits and pushes to this temporary branch attempting to fix the problem.
  5. Wait for the build to finish. If the build failed, repeat step 4.

First of all, this takes a long time. Travis isn’t terribly slow for CI purposes, but when you’re trying to actively debug something, the last thing you need is having your app tests go from 15 seconds to 5 minutes.

Most of all, my problems are usually with PhantomJS. When I can fully control the VM, I can add remotely debug the headless browser on OS X. I can also capture packets creatively with tcpdump(8). Using those tools, I found some pretty heinous race conditions in the Yeti test suite that would have been nearly impossible to find by trial-and-error.