Writing software is easy

If you think building a software product is tough, try building a legendary car from scratch.

Photo courtesy of White Horse Pictures

I recently watched A Faster Horse, a documentary about the development of the 2015 Ford Mustang. It examines how that Mustang, whose nameplate is an icon in Ford’s history (and America’s), went from idea to final shipping product — a five year process.

The amount of work it takes to produce a new car is absolutely dizzying. Take the following list for example, which is just a small sampling of the thousands of high-level items the Ford team is tasked with:

  • Initial idea and design sketches
  • CAD models and full size clay models
  • Engine and transmission development
  • Interior development
  • Software development
  • Supply chain development, management, and parts procurement
  • Cost analysis and pricing structures across hundreds of markets
  • Crash testing and safety/government regulations across multiple continents
  • Dozens of development mules for hundreds of test drives for ride, engineering, and performance tuning
  • Global marketing
  • Global legal
  • Final assembly of hundreds of permutations of the vehicle
  • Global logistics and final shipping to dealers

And if all that weren’t enough, once the car ships, it’s out of your hands. Recalls occasionally happen, but even those are typically for tweaks and safety, not reshaping the car itself.

Compare that to what we do in modern software development:

  • Initial idea, design sketches and quick prototypes
  • Write some code, probably with free tools
  • Find a server for hosting
  • Do some testing
  • Pick a price and build a little marketing around it
  • Ship your product with a few clicks
  • Iterate and ship it again

When I sat back and thought about how vastly different these industries are, a few things jumped out at me:

  • The work that companies like Ford do to bring a car to market is truly impressive. The coordination and teamwork is unbelievable, and it’s a real credit to the power of people.
  • I love working on Basecamp, a product whose fundamental goal is to bring people together to work on getting things done, solving problems, and doing great work — exactly the kinds of things that Ford does to bring the Mustang to market.
  • The challenges I face in my day to day work as a programmer aren’t really so bad. 😎

It’s that last point that really stuck in my head.

We (myself included) can sometimes get bogged down by the challenges in building software. If you’ve ever had a frustrating day of programming, team battles, or a tough interaction with a customer, you know the heavy feeling I’m talking about.

But compared to building a car from scratch, we’ve got it so good — writing software is easy!

Embrace imperfection and ship it 🚢

Of course I don’t mean to trivialize our work or make reductive statements about our day to day problems. We all have tons of responsibilities on our shoulders to make great products that our customers love. On a daily basis we work on problems we don’t fully understand, critical bugs, and important features, all within a set of team dynamics and personalities.

But as hard as it is to tackle those issues, our struggles are relatively tame. If you take a look at the world around you, I bet you can find products that were insanely hard to ship, arguably much harder than software.

I personally think about the engineers at Boeing who are building massive jumbo jets every day. I’m in awe of construction crews who regularly build 50 story high-rises in Chicago. I’m fascinated by the amount of work that went into building my Nexus 6P so precisely.

A car or airplane has to be near perfect when it ships. A building must have every detail planned and triple checked. A phone must be engineered to the millimeter.

But modern software doesn’t have to be any of those things. We have a huge advantage — we can ship imperfection.

Software development brings us incredible freedom — freedom to build and ship things in days, not months; freedom to iterate and tune until our heart’s content; freedom to plan a little, but not excessively; freedom to be imperfect.

I am all for being detail oriented, but perfection is unobtainable in software. I’ll look closely at every detail of a feature and consider all the angles. Often there are imperfections, but if it’s a close call and the feature is good enough, I’ll always vote for shipping instead of holding it back.

This is not to say you should take shipping lightly. You should always consider the impact to your customers and understand any risks you might be taking by shipping an imperfect feature. And I’m not saying you should go rogue and ship things that fall outside the acceptable standards of your team or company.

But it’s also healthy for you and your brain to ship regularly— to put something out there, feel a sense of accomplishment, and let your customers react to it. You can hem and haw all day, but ultimately your customers will be the true judge of your work, not you or the people on your team.

And hey, if it doesn’t work out, just be glad you weren’t building a car. If something goes really haywire, you don’t have to institute a global recall. Refocus on the problem, reconsider it, fix your app, and ship it again. 🤘

We’re hard at work making the all-new Basecamp 3 and its companion Android app great. Check ’em out!

If there’s anything I can help you with, don’t hesitate to hit me up on Twitter!

Fighting the ticking clock in your head

I have this weird character flaw — I have a clock in my head that’s always ticking. It’s a mechanism I’ve built up over the years because I hate wasting time.

In some ways this internal ticking clock is a really handy tool to have. It gives me a healthy respect for time, which means I’m rarely late, I’m generally pretty productive, and ship work in a timely manner.

And when it comes to shipping work, that mental clock can be really handy too. I always have a sense of how far along I am in my time budget — it sharpens focus and is an excellent tool for hammering scope. It’s a perfect way to find out if I can get 80% of the feature for 20% of the work.

On the flip side, the problem with the internal ticking clock is when things don’t go as planned. Sometimes I’ll spend a couple days of a two-week cycle exploring solutions for a problem, only to find that none of them work. All of a sudden I’m 20% into my time budget and no closer to a working solution or shipping the feature.

At that point my internal clock starts yelling, “you’re wasting time!” It starts getting louder and louder in the back of my head. It can become a major distraction unless I quiet it down.

Knock out the clock by shifting your perspective

If you’re like me, you’ll never be able to turn your internal clock off completely. You can’t just pull the battery on your brain. The best thing you can do is just knock it out for a while. 👊⏰

When my internal clock starts getting loud, there’s one thing that has consistently helped me: I temporarily shift my perspective on how I’m measuring progress. Instead of focusing on feature completion, I focus on the other value my work is creating.

This is helpful because it actively moves you away from the idea that value can only be measured by how much of a feature is working. It’s certainly important to ship features in a timely manner, but there are so many other subtle dimensions of work that are valuable uses of your time. 0% functionality after a day of work sounds rough, but a 100% better understanding of a handful of APIs sounds like a good deal, right?

To help me focus on the other valuable aspects of my work, I’ll usually take a minute to ask myself these kinds of questions:

  • Am I learning anything new? Almost certainly. Every new piece of work through my entire career has been opportunity to learn. If you leave any piece of work saying “I knew it all, I got it totally right”, then you’ve probably missed some key learning moments.
  • Has this been valuable, productive time with my team? “Productive” and “valuable” can mean a lot of things. Maybe by talking with your team you came up a clever new solution nobody has ever done. Or maybe you never solved the problem, but you had a ton of fun working with your team. All of those count as valuable and productive in my book.
  • Have I had at least one sharable, teachable moment? If you’re learning regularly, you’ve probably found at least one thing you can share. It doesn’t matter what scale you share at — at your own company, on Twitter, or at a conference talk. Getting out there and sharing is another way for you to learn and reinforce the importance of your daily challenges.
  • Am I identifying any weaknesses I can work on? Even if I’m not producing a finished feature, I’m almost always finding things to improve. It might be a UI tweak, code clarity, or new tooling. Or maybe I’ve identified a weakness in my own knowledge base that I need to improve. It doesn’t matter what it is, if you’re improving anything, it’s time well spent.
  • Am I prioritizing quality? Quality is a broad term, but we take it seriously at Basecamp. If I ever feel rushed by my internal clock, I always make it a point to stop and consider this. Some level of time pressure is healthy for shipping, but not at the expense of quality.

At the end of the day, shipping a feature a few days later is rarely going to have a significant impact in the long run. So if your internal clock is getting on your nerves and causing you to rush, take a breath and put it aside. Consider all the other value you’re creating with your time — I bet it’s a lot more than you might think. 🤘

We’re hard at work making the Basecamp 3 and its companion Android app the best it can be. Check ’em out!

Remembering how I got here — with a lot of help from others

About a month back, Basecamp put out a call for internship candidates. We’re looking for great people who want to learn about programming, product design, operations, data, or marketing directly from the people who work on Basecamp every day.

But before we went public with it, any interested team had to internally pitch a meaningful project and commit to investing the proper time and energy into teaching, guiding, and helping our interns regularly.

The Android team is made up of three people. And of those three, I was the loudest “no” vote. I think it was something along the lines of, “we don’t have time, it’s not a priority.”

I look back on that now and realize how insanely silly and selfish that was.

At every turn of my 15 year career, people have been helping me. Helping me to learn new skills, advance my career, or just to be a better person. I’ve tried to do the same for others over the years.

And yet when I was given such a clearcut opportunity to help someone else professionally, my first reaction was to punt it away because it wasn’t “a priority.”

At that moment, I had completely forgotten how I got to where I am today— with a lot of help from others. Sure, hard work, persistence, and maybe even some smarts helped pave the way. But I sure as hell didn’t build my career all by myself. I needed to remind myself of that. I needed to remember how I got here.

I have no idea what I’m doing

At my first job out of college, I was thrown onto Java projects. I had no idea what I was doing. For over two years, a bunch of people helped me as I fumbled my way through the basics of programming, business, and being a professional. These years laid the foundation of my career. Without the help, guidance, and friendship of a few key mentors, my career wouldn’t have turned out nearly as well as it did. I’m sure of that.


By 2008 I’d been doing Java for a long while, and it was time for a change. I joined an interactive design agency in Chicago, converted to a project manager, and once again had no idea what I was doing. I was running multiple projects with dozens of people, in an industry I didn’t fully understand. I wasn’t doing any programming, but I sure was making a lot of clients angry.

And once again, so many people helped me through it. Veteran project managers taught me the tactics of project delivery, designers helped me understand the intricacies of their work, and account managers helped me handle, persuade, and sell to clients. By the time I’d left, I was a better balanced, more polished professional in all areas of my work, in large part because of the help of others.

Fast forward to today. I’ve been at Basecamp for almost three years, and have been a professional programmer, consultant, and project manager for over 15 years. And yet part of me still has no idea what I’m doing. I’m still getting help from others on a daily basis, from every part of the company. It doesn’t matter what I’m stuck on, there’s always a friendly teammate to help me with all the things that I don’t understand (which is a lot).

Paying it forward

Hopefully by now it’s crystal clear why I felt like such a fool for saying no to the internship idea. I honestly can’t imagine where I’d be today professionally if it wasn’t for for the selfless, generous help of others. But there’s a happy ending to this story.

About a day after I said no to the internship idea, I realized my madness and jumped on board with the idea. And not only did I vote yes, I wrote the formal pitch for our project and will be the point person for our awesome Android intern.

I know I didn’t say thank you enough to everyone who helped me so much along the way. I can only hope that paying it forward now and in the future serves as a small repayment of that debt.

So the next time you’re given the opportunity to help someone professionally, I’d encourage you to really stop and consider it. I know time is short and life is busy. But try to remember those people who helped pave the way for your successes — think of how proud they’ll be to know they’ve taught you well.

If you’re interested in one of our internship projects, applications close on 2/24/16, so you’ve got less than a week to apply. Get a move on!

We’re hard at work making the Basecamp 3 and its companion Android app the best it can be. Check ’em out!

To the Android open source community: Thank you!

While developing the Basecamp 3 Android app over the past year, we’ve leaned quite a bit on some really useful open source libraries.

These libraries did a bunch of heavy lifting for us. They helped shorten our development time, increase programmer happiness (since we didn’t have to write them from scratch!) and ultimately ship a better product.

Open source is such a deep-rooted part of Basecamp’s culture that I think it’s important to give credit where credit is due. I want to, in some small way, show our gratitude to a group of people who probably aren’t thanked all that often.

So, to all of you — the women and men who author and maintain Android open source projects everywhere — thank you very, very much for all your hard work!

The All-Stars

There are lots and lots of libraries out there, so I’d be remiss if I didn’t call out some all-stars that really helped us out.

Big thanks to the teams that build and maintain these libraries — you’ve made our work and lives better! (If you’re an Android programmer, it’d be a good idea to bookmark these if you’re not already using them.)

  • Facebook’s Stetho: A debug bridge that lets you use Chrome Developer Tools to inspect native UI, resources, and data. We use this quite a bit to debug layout issues and stored preference data.
  • Flipboard’s BottomSheet: An easy way to mimic Android’s bottom sheet interaction without writing it from scratch. We use this to power our share sheet, and have some ideas about future uses too.
  • Google’s GSON: Easily serializes JSON into Java objects. We use GSON a lot to serialize JSON data, which makes it a breeze to work with in Java.
  • greenrobot’s EventBus: An event bus that makes it super easy to implement a pub-sub model. We use events for all sorts of stuff, like updating the UI when a background data call finishes.
  • Path’s Android Priority Job Queue: A job manager that has simple defaults, but offers a lot of power too. It’s fantastic for running asynchronous jobs and a wonderful replacement for the dreaded Asynctask.
  • Square’s Retrofit and OkHttp: If you’re doing any kind of API or HTTP work, you need to use these, period. We use Retrofit exclusively for all of our API interfaces.

Giving Back — Turbolinks Android

Like any good citizen of an active developer community, we’re not just going to leech — we’re ready to give back!

In short order we’ll be releasing our first open source Android library — Turbolinks Android. It’s the same adapter framework that’s powered our Basecamp 3 Android app since November 2015, and it’s a crucial component in our native-web hybrid approach. It’s made specifically for Android, and will get your hybrid app hooked up to a Turbolinks 5 web app in a jiffy.

We’ve done our very best to make sure Turbolinks Android possesses all the qualities that we love about the all-stars libraries above: easy to get started, easy to use, fast, and reliable.

We’re thankful that we’ve been able to stand on the shoulders of awesome libraries ourselves, and can’t wait to get Turbolinks Android out to the open source community!

If you’re an Android open source developer and ever want to chat, feel free to contact myself or Jay. We’d love to talk and share ideas!

We’re hard at work making the Basecamp 3 and its companion Android app the best it can be. Check ’em out!

Blow your deadline, blow your budget, and chalk it up as a success!

At the end of 2015, we launched an account switching feature in the Basecamp 3 Android app. On the surface it’s a pretty basic feature — if you’re part of more than one account, you can just tap a menu and flip over to another account.

This feature met all the criteria our team looks for when picking new work to start: it was something customers wanted, it was something we wanted, and it seemed shippable within a two week budget.

The result: We shipped a great version of the account switcher. Success!

The fine print: It took us six weeks to ship. We completely blew the budget and deadline. 😭

Six weeks to ship this? Sheesh.

What happened? How did we balloon from two weeks to six weeks? And how can we call this a success?!

The Problem: We Didn’t Have All The Information

As many programmers have (rather painfully) experienced, we didn’t have all the information up front. When we originally budgeted two weeks worth of time, we assumed that our foundational code was solid enough to keep building on.

That assumption was wrong.

Over time and in the natural rush leading into launch, some things slipped. Our code wasn’t quite as organized as it used to be. AsyncTasks were making our code hard to read, and even harder to maintain. Our local data storage scheme was hard to use. Somehow four different authentication paths got bolted on. Our unit test coverage wasn’t as robust as it should have been.

But none of that was obvious during week one of building this feature. Or even week two. Or even week three. You get the picture.

The Real Measure Of Success: Laying The Groundwork

Sam Stephenson, a programmer at Basecamp and one of the smartest people I’ve ever met, said it best:

Then, instead of solving the problem with an ad-hoc, one-off change, lay the groundwork for a general system that facilitates the specific change you want to make.

That, in a nutshell, explains how our two week feature turned into a six week mini-project. And it’s why we absolutely classify this venture as a success.

We ripped out AsyncTasks and replaced them with Android Priority Job Queue. We rewrote our entire data storage system. We cleaned up our authentication code. We wrote new tests and improved others. We did a bunch of things that would take too long to list here. We did everything we could to improve our general systems for future work. (And oh yeah, we wrote all the new code to make switching accounts work too!)

In short, our team recognized the incredible value in doing things the right way, not the fast way. We knew that rewriting, refactoring, and reorganizing large chunks of our codebase was a worthwhile effort to give us a more solid foundation going into 2016.

Yeah, we could have shipped this feature in two weeks. But it was far more important to lay a solid groundwork in six weeks. We respect our deadlines, but we respect the quality of our work much more.

What Did We Learn?

Even though we were happy with the end result, there were certainly things we could have done better. So what did we learn?

  • 📅 After one or two weeks, we could have paused for a couple of days and taken a step back. This would have given us time to analyze more deeply, reset expectations, and set a new soft deadline. Even if we came to the same conclusion / deadline, resetting still would have been beneficial for getting us all on the same page and reassessing our current priorities.
  • 🎥 As soon we had a feeling this was going to take more than two weeks, it would have been helpful to schedule regular Google Hangouts for our team. Discussing things “face-to-face” (in moderation) can really bring out a lot of good ideas and attack vectors to problems.
  • 📝 We could have done more frequent, small written pitches to help describe interactions and systems. When discussing something complex, sometimes rapid-fire conversations in Campfire can be hard to follow. Luckily, Basecamp gives us a lot of options like to-dos, documents, or messages to take things down to a slow gear — letting us write more methodically and thoughtfully to clarify our thinking.
  • 🏃 Rushing gets you nowhere. There were a few moments where I felt the need to push harder, to rush, to race to the finish line. I think that’s only natural when you’re motivated and want to do great work. But my teammates were supportive and we were able to refocus on the long-term. Great teammates will always help you make the right decision.

So in the end, we shipped a pretty nice feature, laid the groundwork for 2016, and learned a lot along the way.

I guess doing all that in six weeks doesn’t seem so bad. 🎉

We’re hard at work making the Basecamp 3 and its companion Android app the best it can be. Check ’em out and let me know what you think!