3 remote developers, 1 million happy users
How we leverage our team & tools at Lonely Planet to be more effective
On the mobile team, we set out in 2015 with the task of building the best app for travelers on the ground in any location in the world.
After a year in development and another one out in the wild, we believe that our first version of Guides has succeeded in its goals.
I would like to share some of them with all of you.
Embrace limitations & differences
We are a very small team trying to change how things work at a company that’s been inspiring travelers for almost 44 years. We don’t have the capacity to take on every challenge so we’ve had to constantly pick our battles. It’s been frustrating many times but we all know that constraints stimulate creativity.
Prioritize and simplify ruthlessly
I can only imagine how many unneeded features, animations, libraries and architectures we would’ve built if we’d had the resources. We couldn’t so we didn’t, and as a result, the app has been reduced to its most essential, valuable features.
For every feature that we have created we have asked ourselves, does this make sense? How can we make this simpler? How can we test this? From design to development, we’ve strived to make things simpler and easier, not only because we wanted to, but also because we had to.
Use tested architectures and patterns instead of experimenting
When we started thinking about the architecture of the app, there was a lot of hype around VIPER and clean architectures, especially on iOS. A lot of people were starting to implement them but no one seemed to have experience with them in the longer term. We didn’t want to hold ourselves hostage to maintaining so much scaffolding, so we decided to build our app with more conventional approaches, while also avoiding common pitfalls.
For instance, apps we’d built in the past often ended up with Massive View Controllers. To avoid that issue in Guides, we factored out all functionality that didn’t belong in them, using data controller classes to handle all the data, view models to manage the state of views, and helper classes that do things ranging from managing the user location to sending notifications or handling all of our custom font styles.
We are very happy with the results. This simpler approach has allowed us to re-use and test code very easily, without having to write a crazy amount of boilerplate code.
Make good use of our global team
We are spread across multiple continents in cities like San Francisco, Salt Lake City, Nashville and Madrid. There are certain limitations inherent to the nature of our team, but over the years we’ve learned how to take full advantage of them and become very effective.
One of the most positive things about being distributed across multiple time zones is that we all get our share of maker schedule. Designing and programming are creative endeavors that are performed best in an interruption-free environment. I consider myself very lucky to have mornings to myself, where I can just focus on my tasks at hand without any interruptions.
The second best thing is that by not having a lot of overlap we can pick up where the other leaves off and continue working. If I don’t finish an important task before the end of my day, somebody else can pick it up and run from there. The first thing I do when I start working is review other people’s work. So we’ve fallen into this nice pattern where we minimize interrupting each other and allow ourselves to concentrate on what we are doing.
The tools we use are the usual suspects. GitHub is where we manage pretty much everything. Even product and design tasks take the form of GitHub issues. We use milestones to give shape to our bi-weekly sprints and issues to define tasks within them. We try to keep our issues and pull requests small and focused, so that they are easy to implement and review. If something looks like more than a day of work, we break it down into a smaller items.
Slack is where we talk to each other. With it, we’ve pretty much removed the need to use email. It allows us to both have timely discussions, but also a timeless backlog of all the decisions that have been made along the way.
Unite design & development within a single team
One thing that’s special about our team is how different disciplines work closely with each other. We’ve worked hard to blend the product, design and development disciplines into one team. We developers will give early and frequent feedback on design specs, and our designers will pull and run our code to give feedback as we implement the designs.
We all participate in each other’s process, providing our perspective as early and frequently as we can, and doing so while minimizing interruptions by doing it asynchronously.
Tighten feedback loops
Given that we are a small team we felt like we needed to improve the speed and amount of feedback about the quality of our apps. That made us invest really early on in automated testing and a good crash reporting tool.
Testing & continuous integration
For our other apps we had written a lot of UI tests but they had a couple of problems. They were really high-maintenance and didn’t expose many of the errors we wanted to catch. For Guides, we decided to go all-in with unit testing. Our architecture allows us to isolate components fairly easily, and therefore test them without much difficulty.
When rushing to ship the 1.0 version of Guides, having to write unit tests for most of the code made it a real pain in the neck. We were going much slower than we would have otherwise and that made us feel slow and unproductive.
However, that all changed when we shipped and started iterating on features. Thanks to having good test coverage, it is incredible the amount of confidence we have now in making changes. It’s a game changer.
To run the tests we use a cloud-based continuous integration platform that executes all of them every time we push a commit to our Git repo. That allows us to keep working on other features or bugs while the tests are being executed, minimizing downtime.
When you put your app in front of thousands of people things you never imagined start happening. Crashes and errors pour in like crazy.
Having a good tool that collects them all and organizes them by type of crash is one of the most important tools to invest in. It allows you to quickly determine the most outstanding issues so you can focus on those.
Direct feedback channels with users
We personally review each request and respond appropriately. This keeps us grounded and in contact with our users’ needs and wants.
One more thing that we’ve done is hook App and Play Store reviews into Slack using AppFigures. It posts every review we get to a channel so we are on top of everything people say about our app.
Travel a lot and use our own app
Not only do we take feedback from our users, but our team is made of avid travelers and during the past two years, we’ve traveled to 25+ cities that we have in the app, forcing us to use it like real tourists.
That has allowed us to surface tons of issues and recognize new opportunities for the app. In fact, many of the current features of the app have come from using it ourselves.
Frequent team hangouts & meet-ups
Even though we all love working remotely, this team wouldn’t function as well as it does if we hadn’t focused, apart from chatting on Slack, on in-person meetings and frequent hangouts with each other.
We try to meet in person two or three times a year. This is especially important when someone new comes aboard, since it allows us to introduce ourselves and get to know each other a little bit better. I’ve personally noticed a huge difference in the way I feel around people online after I’ve met them offline.
For the day-to-day work, we do our daily meeting in Hangouts. It allows us to see and have small talk to one another a little bit.
For a while, we were very serious in the daily meetings, it was all about work. We would go around explaining our completed tasks/tasks to do/blockers but we wouldn’t talk about anything else.
At some point we realized these meetings were more than just work. It was the only time in the day when we would actually talk to each other so we needed to make them more fun and conversational.
So we started having small-talk about other stuff right before and after the meeting. That alone changed the tone of it, and allowed us to relax and enjoy that time a bit more.
Having constraints in your team and process is not necessarily a bad thing. If you embrace them, they might even become one of your biggest assets.
Remember that this is what has worked for us. We have tried not to follow any mantras and just do what is right for our team and circumstances.
Please do the same.