Rewriting bad writing

Become a better writer by taking a poorly written piece and rewriting it yourself

Once in a while I read something so complex and poorly written, when I’m finished I have no idea what I just read. It’s insanely frustrating.

While writing isn’t an easy skill, people make it way harder than it needs to be. They think choosing complex language shows skill and smarts.

It doesn’t! Writing plainly and clearly does.

Somewhere along the way, Jason Fried dropped a lesson on our team: if you think something is poorly written, rewrite it.

It 1) is a chance to learn 2) shows you’re willing do the work beyond complaining and 3) helps you think about how to handle a similar situation. Ultimately the exercise makes you a better writer.

Let’s do it.

Case study: A Mozilla project announcement

Below is an overly complex, hard to read project announcement. Try to fight your way through it. 😰 My rewrite follows.

Disclaimer: This is an isolated critique of a single piece of the author’s writing. It’s absolutely not about them as a person or their other work. I’ve written plenty of bad stuff too. Please feel free to go back and critique the hell out of my writing, it’s a good way to learn.

Mozilla’s version

Announcing Project Mortar

In order to enable stronger focus on advancing the Web and to reduce the complexity and long term maintenance cost of Firefox, and as part of our strategy to remove generic plug in support, we are launching Project Mortar.

Project Mortar seeks to reduce the time Mozilla spends on technologies that are required to provide a complete web browsing experience, but are not a core piece of the Web platform. We will be looking for opportunities to replace such technologies with other existing alternatives, including implementations by other browser vendors.

In order to keep costs low, we may use APIs internally that are not considered web standards. These APIs will not be exposed to the web. Solutions that both reduce our support cost, achieve the desired user experience, and make use of web standards will be preferred.

The project will start by investigating how Firefox handles PDF rendering followed by looking into lower cost approaches to providing Flash support as it’s usage continues to decrease. Project Mortar is currently investigating using the minimum set of Pepper APIs needed to support the PDFium library and the Pepper Flash plugin. If successful, this work will allow us to completely remove NPAPI support from Firefox once NPAPI is disabled for general plugin use.

Keep an eye on for status and future updates for this project.

Here are the main problems with this announcement:

  1. Its super long sentences are hard to parse and understand.
  2. It uses a lot of impersonal third-person language.
  3. There’s too much detail/fat drowning out the main message.

Let’s fix those and see what we can learn.

My version

Today we’re launching Project Mortar.

The goal: advance the web by reducing Firefox’s complexity and long-term maintenance.

We all want to make the best browsing experience for our users. That means we need to spend less time building non-core web components. Especially when we can replace them with existing alternatives.

We’ll keep our eyes open for the best options, like those based on web standards. Occasionally we may need to use our internal, closed APIs. Together they’re our best chance at reducing support costs while still giving users a great experience.

We’ll start with two major areas in Firefox — PDF rendering and Flash.

We’re starting with PDFium and Pepper Flash as possible replacements. We’re currently looking at what Pepper APIs we need to pull this off. If all goes well, we can completely remove NPAPI support after it’s disabled for general plugin use.

We’ll continue to post updates on the project wiki.

As always thanks for reading and for your continued support!

I don’t mean to pat myself too hard on the back, but I think that’s a a lot clearer and easier to understand. 😉

What do you think? Better or worse? What did I do right or wrong?

Write your version in the comments below and let’s discuss — remember, it’s a good way to learn!

If this article was helpful to you, please do hit the 💚 button below. Thanks!

Writing is a big part of what we do at Basecamp. It plays an important role in making Basecamp 3 and its companion Android app as great as they can be. Check ’em out!

Your ideas are important — share them with the community

Sharing your ideas helps you and others get better. Here’s how to get started.

At least once a week I say to myself, “That’s interesting. I should write something about it.”

And then I don’t. A bunch of excuses fly into my head.

“Lots of people have already covered this. I’m not an expert. Why would anyone care what I think?”

Sound familiar?

I need to constantly remind myself to stop making excuses and that it’s important to share my ideas with the community.

Maybe I can convince you to do the same?

Ditch the excuses

The fundamental flaw in these excuses is assuming your perspective isn’t valuable to others. It’s a convenient excuse to say your viewpoint isn’t unique, so why bother.

But really it’s the exact opposite.

Your perspective is 100% unique — a composite of thousands of life experiences that nobody can replicate. Nothing that’s ever been previously shared has been through your words and the lens of your experiences.

So don’t worry about being original. You already are.

Understand the importance of sharing

You still might be wondering — why should I spend the time and effort to share?

It helps you

Sharing teaches you how to build compelling stories and make persuasive arguments — clearly and concisely. You’ll learn something new about your work every single time you share.

Don’t worry if you’re “just” a beginner. If you make a mistake, the community will offer helpful tips on how you can improve. That’s free advice from a bunch of experienced people that you can learn from!

And don’t forget — you’re simultaneously leveling up your portfolio. Over time you’ll build up a fantastic body of work you can point to at any job interview.

It helps others

Whether you recognize it or not, you didn’t get to where you are alone — you’ve learned and improved with help from a lot of people.

Any time you’ve read a blog post, used an open-source library, or learned from a conference talk, it’s because someone else helped you by sharing their ideas.

So it only makes sense to give back to a community that’s helped you so much already (and will continue to do so).

Don’t worry, it took me a long time to realize this too. But I encourage you to really think about it sometime. It could really serve as strong motivation for you to start putting your stuff out there too.

Get started

Hopefully by now I’ve convinced you that 1) your perspective is valuable and 2) it’s worth your time.

So how should you get started?

Keep your eyes and ears open for inspiration

I read, watch, and listen to a lot of stuff that inspires me to share my thoughts. Sometimes I agree with them, sometimes not.

But the more you consume, the more chances you have to come up with shareable points or counterpoints. Not to mention, simply consuming content is a good way to learn.

Focus on topics that are important to you

I usually loiter at the intersection of learning/teaching, Android, Kotlin, arguing against excessive work, and the importance of teamwork — all things I care about.

Find the subjects you care about, not trending topics. You’ll know you’re on the right track when the ideas are flowing and don’t feel forced.

Find a medium that works for you

For me it’s writing. But there are lots of other ways. Talk at a conference or local meetup. Record a podcast. Shoot a video series. Contribute to an open-source project. Write a gist and tweet it out.

There’s absolutely no shortage of ways to get your ideas out there.

Look at existing examples of sharing that you liked

Read other people’s writing, watch their videos, and listen to their podcasts. What did you like? What would you differently? Use existing content as a model, then make it your own.

Just start!

Inertia is an absolute killer when it comes to sharing, so getting started will be the hardest part. You’ll be a little nervous and overanalyze everything you make. I certainly was.

I wish I had better advice, but you’ll just need to fight through it and get some stuff out there. Once you get past the first couple, it gets easier — and your content will get a lot better too.

I hope I’ve convinced you to start sharing! If you need any help, you can always hit me up on Twitter.

If this article was helpful to you, please do hit the 💚 button below. Thanks!

In addition to sharing and teaching, we’ve been working really hard to make the all-new Basecamp 3 and its Android app as great as they can be. Check ’em out!

My favorite people and resources to learn Android programming from

Keep your skills razor sharp by following these fantastic people and resources in the Android community

One of the best ways to learn Android programming is to surround yourself with people better than you — then watch and listen intently.

So here’s my attempt to help you find the best to learn from. Below is a list of some of my favorite people and resources in the Android community to help in your quest for excellence.

A big thanks to all these people and groups for making us all better Android programmers! 🤘

🐦🌟 Twitter

I’ve really enjoyed following these Android community members on Twitter.

These folks aren’t just knowledgeable teachers and key open-source contributors. They’re also positive-minded, hopeful, and friendly. Those qualities are just as important to me as being an expert in the area.

Chiu-Ki Chan — A devoted learner and teacher, Chiu-Ki does it all. She interviews folks, runs 360|AnDev, teaches on Caster, speaks, draws, writes, and probably does 100 other things I don’t know about. 😉

Donn Felker— Not only an Android GDE, Donn’s got a great blog full of helpful posts. He’s also half of the Fragmented Podcast along with Kaushik Gopal (who’s pretty sharp in his own right). And if that weren’t enough, Donn’s also the head honcho at, a fantastic site for video tutorials.

Jake Wharton— Honestly, if you don’t know who Jake is, you might be in the wrong place. Just go here now. 😆

Kristin MarsicanoAn instructor at Big Nerd Ranch, Kristin has a wonderful down-to-earth vibe and is clearly a great teacher. Her recent talk at 360|AnDev on the activity lifecycle is a great refresher for something you probably don’t think about enough.

Ryan Harter— Ryan’s a GDE who’s been teaching a lot lately about how to reduce boilerplate code. He also helps run GDG Chicago West and is an instructor at Caster.

The Practical Dev —OK, this isn’t technically Android specific. But it’s such an informative and entertaining commentary on programming, I had to include it. Sometimes reading general programming posts can be really enlightening (and hilarious).

(Note: It’d be impossible to write about every single person who’s a great Android teacher, but you can find more on this extended Twitter list that I’ll keep adding to.)

📻 Podcasts

You should listen to Fragmented!
  • Fragmented— Produced by the aforementioned Donn and Kaushik, this is probably my favorite podcast. Two independent developers with their unique personalities and perspectives, with a focus on purely technical talk for Android.
  • Android Developers Backstage — The most official Android podcast you can get your ears on. Straight from the people who…well, created Android.
  • Material— Material isn’t a technical podcast, but is a lighter listen and a great way to get your Google news. Great for a Friday afternoon. Voices include Russell Ivanovic (from ShiftJelly, creators of Pocket Casts), Yasmine Evjen, and Andy Ihnatko.

📺 Videos

An example of Realm’s super cool synced video and presentation.
  • — Another Donn Felker production, Caster has a over 100 lessons (and growing) of stuff you should know. If you ever watched a video from RailsCasts back in the day, it’s got a similar vibe.
  • — I’m admittedly a little confused by Realm. They have a cool database product, but on the side they also host fantastic talks — transcribed with video and slides that are synced up beautifully.
  • Android Dialogs (YouTube) — A fun little video series where the aforementioned Chiu-Ki Chan and Huyen Tue Dao interview a bunch of folks in the Android community.

📰 Newsletters

Android weekly — the best in Android all in one place.

📚 General Reading

🗣 Conferences

To be totally honest, conferences are tough for me. No fault of the conferences — I’m just terrible at striking up conversations with new people! 😶

Of course they do have a ton of value — meeting new people and learning directly from the community is an irreplaceable experience.

Jay Ohms, Russell Ivanovic, Kaushik Gopal, and me @ Google I/O 2016. 😁

Google IO is the only Android-specific conference I’ve been to, so I don’t have much to compare to. The sessions were top notch (logistical issues notwithstanding), and just about everyone you’d want to meet is there. The downside is that it’s so large, it can be hard to get into the sessions you want or meet up with new people you don’t already know.

There are two conferences I’ve never been to but have my eye on: the intimate 360|AnDev Conference (hopefully it’s back next year) and the more established Droid Con NYC (maybe next year I’ll remember to actually get a ticket).

Whether you’re just starting out or are a wily vet of the Android programming world, I hope this article was helpful to you! If so, please do hit the 💚 button below.

And if you have any Android favorites of your own, please share in the comments or on Twitter — I’d love to find even more great people and resources!

Along with learning daily, we’ve been working really hard to make the all-new Basecamp 3 and its Android app as great as they can be. Check ’em out!

5 steps to creating frustration-free Android test devices

How to setup devices so that manual testing doesn’t crush your soul

A few days ago, I picked up one of my test devices to try out some new code. I couldn’t believe how frustrating it was.

I wasn’t logged into the right accounts. I didn’t have the right apps installed. By the time I finished testing, I couldn’t even remember how to reproduce the bug.

And like any Android programmer, my testing frustration was magnified because we support numerous OS versions/devices.

To save my sanity, I built a system for a unified, predictable setup on every device. Here’s how to do it.

1. Install the OS versions you support

Depending on what API levels you support, ideally you have a 1–1 device to API ratio. This isn’t always possible of course, but it’s helpful.

So first things first — take an inventory of your devices and which ones support which OS versions. Then examine what your customers use the most and optimize for those scenarios.

With that in mind, my lineup looks like this right now:

To truly embrace your OCD like me, slap a version label on the back of each device. 🤓
  1. Nexus 5 (5.1.1) — The Nexus 5 the most valuable device in my lineup. It’s supremely flexible and can run all the OS versions that most users have (4.4–6.x).
  2. Nexus 5 (6.0.1) — More than 50% of our customers are on 6.x. This is currently my baseline test device.
  3. Samsung Galaxy S6 (6.0.1)— Samsung devices make up a good chunk of our users, so it’s important to have at least one representative device. Their implementation of certain features (particularly WebView) can be different, so it’s important to test non-stock Android devices.
  4. Nexus 5x (7.0)— A newer device where I can test the very latest Android builds and features.
  5. Nexus 6P (7.0) — Not totally necessary, but it can be helpful to have one big screen device to see how things look in the real world, as compared to something closer to the 5″ size. Also gives me some flexibility to move down to 6.x as needed.

(I admittedly don’t have a 4.4 device, and rely on a Genymotion VM to test for that. I’ve debated knocking down my Nexus 6P down to 6.x, and flashing a Nexus 5 to 4.4).

2. Install and configure a common set of testing apps

You’ve probably got a common set of apps you rely on to test your app. This is the time to make sure they’re all installed, logged in, and preferences tweaked to your liking.

App choices will vary person to person, but here are a few that I rely on and recommend:

  • 1Password — Keep all your passwords secure, and makes logging in to apps so much easier. Always the first app I install.
  • AZ Screen Recorder— Great for screencasts or to create gifs to share with teammates.
  • Chrome Beta — We do a lot of WebView work, so we want a heads up on how future versions of Chrome/WebView will behave.
  • Dropbox — Automatically uploads screenshots so I can grab them from my computer quickly. I also use it to do some file-based testing.
  • Flesky / Swiftkey / Google Keyboard — Writing on our homegrown rich text editor, Trix, is a big part of our app. So we test various keyboards frequently.
  • Keep — Super handy to save quick notes, URLs and whatever else synced up across devices.
  • Solid Explorer — The best file manager I’ve found. Moving things around in the file system can be very handy.

3. Login everywhere

It sounds painfully obvious, but with so many devices floating around, you might not actually be logged in everywhere you need to be. Inventory your standard places to login and do it.

Typically for me this means logging in to just a handful of places:

  1. 1Password for Teams
  2. Google — Personal
  3. Google — Work
  4. Dropbox

It’s basic but there’s nothing more annoying than getting into your testing and realizing halfway through you’re not logged in to the right accounts.

4. Use Nova Launcher for a consistent experience

This was the real game changer for me. Using Nova Launcher, you can make every device look and work the same.

Nova Launcher all the things. 🚀

For me the biggest irritation was the launcher/app organization being different on every device. Everything was hard to find and it slowed me down.

Nova solves all of this.

You can setup your home screen, dock, and app drawer once, then share that across devices. When you pick up another device, your apps are in the exact same place as you expect. It’s predictable and fast— no hunting, no mental overhead.

Here’s how to do it.

  • Pick your favorite device and install Nova Launcher. Buy and install Nova Launcher Prime (this unlocks a set of handy features).
  • Set Nova as your home screen launcher, replacing whatever you’re currently using.
  • Open Nova settings and play with all the settings. There’s too much to cover here, but take the time to make it work exactly how you want. Nova’s customizations can do anything your heart desires.
  • When you’re happy with the setup, in settings go to “Backup & import settings”. Backup your current settings to Dropbox (or wherever).

  • Pick up one of your other devices. Install Nova again.
  • Go to “Backup & import settings” again, but this time do a restore. Pick the file from Dropbox (or wherever) that you saved in the previous step. Repeat for all devices.
  • Voila — your devices now all look and work the same!

The long-term beauty of using Nova is that as your apps or preferences change, just upload a new backup and restore it on all your other devices. You’re all set again!

5. Tweak all your sytem settings

The last thing to do is go through all your system preferences and get them working the same on each device. For me that means:

  • Making sure all my wifi networks are setup (home, office, favorite coffee shops)
  • DND/total silence is activated. Test devices don’t need to notify me about anything.
  • Developer options and USB debugging is enabled
  • Screen stays awake when plugged in (developer options)
  • Screen brightness is set to a level I like (with adaptive brightness off)

Optional: live with it

One thing I like to do is swap devices from time to time and “live” with our app for a day or two on that device.

Using the app on a real device under real scenarios gives valuable perspective. You can tell if everything looks, feels, and performs as you’d expect.

To make this process easier, a couple tips:

  • Use a nano SIM from your cellular provider, and keep a SIM card adapter set handy. Even though all newer devices use nano SIM, you still might run into micro SIM slots (or if you’re really lucky, a standard SIM slot!)
  • Install apps that you use outside of work. This helps ensure you don’t jump ship back to your daily driver, and you give the test device a real shot. But keep your personal apps in a separate tab in Nova’s app launcher. That way your testing apps are still front and center, but you can still get to the fun stuff and live with the device for a bit.

That’s it, I’m glad you made it this far! Following these steps should help reduce your manual testing frustrations, and hopefully keep you in the zone doing the more fun stuff (like programming everything that needs to be tested!)

If you liked this post, please do hit the 💚 button below. I’d really appreciate it!

I’m part of a fantastic team that builds (and tests) Basecamp 3 and its companion Android app. Check ’em out and let me know what you think!

It’s OK to be pragmatic (with a little help from the “crazy ones”)

Being pragmatic is engrained in me. I’m at my best being practical and boring.

Here’s the problem — experience has taught me that you’ll never do your best work through sheer pragmatism alone.

While I’m good at weighing options and making decisions, I’m not that visionary who can conceptualize grand ideas.

While planning comes very naturally to me, I find it difficult to inspire others.

And though I’m good at shipping, I often do so using following established conventions.

So while the incremental, risk-averse nature of being pragmatic can be good for many aspects day to day of work, it’s not everything.

What you’re good at and what’s good for you aren’t always the same thing.

To make long-term, deep progress in your professional growth, you need to think big sometimes.

You need to try things that don’t have predictable outcomes. You need ideas and ways of thinking that inspire innovation. You need to stretch way beyond your comfort zone.

But as a pragmatist, how can you do all this when it’s so foreign to you?

Surround yourself with the “crazy ones”

The idea of the “crazy ones” may be Apple’s, but that kind of creativity, inspiration and genius is all around you.

Look for opportunities to work with people who are the opposite of you — the dreamers, big thinkers, and contrarians.

These will be the people who will push you toward bigger and better things.

Yes, it’s going to be very hard and uncomfortable for you. You’re going to feel like you’re on a bizarro planet where everything is backwards and nobody thinks like you.

This is a good thing.

Having people challenge your baby-steps thinking with big-leaps thinking is a good thing.

Not understanding what the hell one of your colleagues is thinking (at first) is a good thing.

Having healthy discourse around big ideas is a good thing.

And shaking hands and finding compromise is a great thing.

Their thinking will seem crazy and executing their ideas will seem impossible. But in end you’ll pull it off — not in spite of you, but because of you.

You’ll be better in every way because you stretched well outside your comfort zone. And really, what’s more rewarding for a pragmatist than shipping something you didn’t think was possible? 🤘

If you liked this article, I’d sure appreciate if you clicked the 💚 button below. Thanks!

I was lucky enough to work with some of the crazy ones on Basecamp 3— especially Jamie Dihiansan, the designer of the Basecamp 3 Android app. Check out what happens when you get a happy mix of pragmatism and crazy!

Silicon Valley arrogance: “I can tell you which startups will succeed, without even knowing what…

According to Marissa Mayer, long hours and weekend work (in person) will lead to success

Yesterday I read this article about Marissa Mayer. This quote infuriated me (emphasis mine):

My husband [the venture capital investor Zachary Bogue] runs a co-working office in San Francisco…And if you go in on a Saturday afternoon, I can tell you which startups will succeed, without even knowing what they do. Being there on the weekend is a huge indicator of success, mostly because these companies just don’t happen. They happen because of really hard work.

I read my fair share about the tech world. I haven’t encountered statements this utterly arrogant and silly in a while.

Let’s break down that quote. She’s saying…

Keep reading “Silicon Valley arrogance: “I can tell you which startups will succeed, without even knowing what…”

Life as an impatient programmer

Gavin Belson insults my spirit animal — “the insolent and cocksure hare.”

I have to admit — patience has never been one of my strengths. My parents tell me over and over, “Try to be more patient!”

It’s never quite stuck.

I get why they harp on me. Impatience is by definition pretty negative sounding:

1. having or showing a tendency to be quickly irritated or provoked.

But is being impatient always such a bad thing? Consider the alternate definition:

2. restlessly eager

“Restlessly eager”. I love that!

Said a different way, it means you’re enthusiastic, dedicated, and ambitious. You just have a little trouble directing all that energy.

But what if you could harness all that enthusiasm?

The positive results of impatience

It may sound strange, but being impatient has helped shape my programming career in a positive way.

If you’re like me, being impatient can help you become…

  • A better programmer. You won’t wait for someone else to fix a bug or an annoyance. You’ll create that app you need because it doesn’t exist yet. You’ll build systems and shortcuts for your daily work. This process of constantly building, learning, and tweaking keeps you sharp.
  • A well rounded professional. You won’t stay in dead end jobs that don’t challenge you. You’ll want to learn new things. You’ll want to improve stuff as fast as you can. This builds an arsenal of rich experiences that you can carry forward forever.
  • A better student. You’ll be an efficient learner. You’ll learn the stuff that matters and ignore the fluff. You’ll develop systems to learn faster and smarter. You’ll focus and work hard because there’s nothing worse than wasting time.
  • A better teacher. You’ll have spent so much time learning, you’ll already be a great teacher. You know what matters and what doesn’t. You’ve experienced success and failure in a wide variety of situations. You’ll want to pass on these experiences onto others.

Hey, being impatient doesn’t sound so bad after all!

Harness your impatience

I know, I’m making it sound like being impatient is all roses and it’s the key to success.

Of course it’s not that simple. Harnessing your impatience into positive energy is easier said than done. I’ve fucked up plenty because of my impatience.

Over the years I’ve found that, like many things, balance is the key. Not everything can be the ire of your impatience.

Try to pick your battles. Try not to get worked up about minor bullshit. Try to direct that energy at the important stuff.

Ask yourself lots of questions. When do you get impatient? When did you turn that energy into a success? When did you fail? What’s worth spending that valuable energy on? Who on your team can help keep you in check?

If you can answer those questions, you’ll be on your way toward harnessing your impatience.

You’re lucky. Not everyone is blessed with impatience. It’s a powerful motivator and a great source of energy. Use it to your advantage!

If you liked this article, I’d really appreciate if you click the heart button down below. Thank you!

We’ve been hard at work making Basecamp 3 and its Android app the best way to run your projects and small business. Won’t you give them a try?

It never hurts to ask

A simple, effective piece of advice from Jason Fried

A couple of years ago, Jason Fried gave me the simplest, most effective advice I’ve ever received:

It seems so obvious, something you’ve probably heard before: it never hurts to ask. But when you actually put that advice into practice, the results are rather amazing.

In 2014 we sponsored a project management conference. As sponsors we got all the usual promotion: our logo on some slides, some tweets, email callouts, etc.

We wanted to get the most out of our sponsorship, so Jason encouraged me to get creative with what we could do. Here’s what I said:

Jason completely agreed, but I couldn’t think of a good way to pull this off. How could we clearly announce who we were and give them a sense of our friendly personalities? 😁

Aha, what a great idea — that would accomplish exactly what we wanted!

But…stage time wasn’t part of any sponsorship package they offered. And as one of the world’s worst negotiators, I was hesitant to ask for something outside of the existing options. 😶

But I needed to learn. I got over myself. I sent an email to the organizers asking nicely and explaining why it was so important to us.

You can probably guess what happened next. We got our stage time. The organizers were happy to accommodate us. It wasn’t a big deal at all.

And from that one success, I burned Jason’s advice into my brain: it never hurts to ask.

Since then, I’ve had plenty of success with Jason’s advice. Yet I’m still fascinated by how well it works.

Last week I was reminded how simple and powerful “just asking” can be.

I’d written an article about how I built my first Android open source library, and was looking for ways to share it beyond our normal blog audience.

I’m a big fan of The Practical Dev, and I figured the article might be of interest to their audience. But how could I get them to share it?

I remembered Jason’s advice — it never hurts to ask. So that’s exactly what I did. I sent them a link to my article and politely asked if they’d consider sharing it. A couple of hours later they were nice enough to do so. Success!

Perhaps unsurprisingly, this advice can also apply to product design.

In the Basecamp 3 Android app we recently added a “what’s new” dialog. This lets customers know what new features we added, but also gives us a chance to ask for their review.

Any idea when we started asking for reviews? 😏

I fully admit I was skeptical that a simple “rate us” button would have any impact our ratings.

Wow, I couldn’t have been more wrong. Our positive ratings and reviews skyrocketed! 🚀

Once again Jason’s advice held true — all we had to do was ask for reviews, and people were happy to do it.

I can’t tell you how many times “it never hurts to ask” has turned out positively for me. Even if I don’t end up getting what I hoped for, it’s still nice to know that I at least asked. Nobody gets offended or upset by reasonable requests. ¯\_(ツ)_/¯

I think this comes down to one fundamental truth: people want to help you.

Sure, not everyone is super generous. But as a rule I think most people try to be. If you ask for something in a nice, humble, and confident manner, they’ll try to find a way to help you.

So the next time you want something, remember: it never hurts to ask!

If you liked this article, I’d really appreciate if you click the heart button down below. And if there’s anything I can help you with, just ask!

We’ve been hard at work making Basecamp 3 and its Android app the best way to run your projects and small business. Won’t you give them a try? 😀

How I built my first Android open source library (and how you can too)

A practical, step-by-step guide for building your own open source library.

In early 2015 I recognized a major hole in my professional work — I hadn’t made a single open source contribution. That’s pretty embarrassing to admit, considering I work with some major open source contributors on a daily basis.

Shortly after that depressing realization, I set a goal for myself: find a way to make at least a few small open source contributions within the next year.

As luck would have it, I knew that Turbolinks 5 would be released in early 2016. And one of the goals of the Turbolinks 5 project was to have adapter libraries for all three major platforms — web, iOS, and Android.

So having never done any open source work at all, what did I do? I volunteered to lead the charge and build a brand new Android open source library from scratch. 😳

Sure, I stumbled along the way, but in the end I somehow figured it out and we successfully launched Turbolinks Android in February 2016. 🎉

Why create a guide like this?

Creating an open source library has been such a rewarding, fulfilling experience — so much so that I want to encourage any open source newbies to give it a shot.

But hey, I get it — if you’ve never open sourced anything before, it can be a bit daunting. You don’t know how or where to start and you don’t have a map to tell you where to go.

And that’s exactly why I wrote this gigantic article —to hopefully give open source newbies some general direction on how to get started.

Keep in mind, this is based solely on my experience, and I’ve only done this once. Still, if you’re just getting started with building your own Android open source library, I hope it helps. Onward!

Step 1: Build a real app for yourself

First and foremost, build an app that does what you need it to do. Don’t worry about open sourcing anything at this point.

This is important — you don’t want to get bogged down with a bunch of questions about open sourcing that don’t matter yet. Hell, you don’t even have anything to open source yet!

Just keep building your app as you normally would. Your goal at first is to take care of yourself and make a great app, not worry about other people and their projects (at least, not yet).

And build only what you need — nothing more, nothing less. If you start worrying about open sourcing too early, you’ll start making premature design decisions in your code, like prioritizing “flexibility” over convenience and clarity. It’s not worth it— you’re just making complete guesses!

Step 2: Identify a problem your code is solving

Once you’ve got your app in a good place, it’s a perfect time to look at your code and determine what parts of it might be useful to others.

Scan your app and keep an eye out for…

  • Code you’ve re-used from a previous project. If you’re borrowing code from something you worked on before, there’s a good chance it’s doing something useful and could be bundled up as a library. At the very least, it’ll save you the trouble of using it in your next project.
  • Code that’s “your version” of another third party library. If you’ve written code that does roughly the same thing as another library, that’s actually a good indicator of a potential library. Even if your implementation is similar, how you approach the problem — your style — is what will come through. If existing libraries didn’t meet your needs, then there are probably hundreds of developers who are in the same boat.
  • Code that solved a particularly difficult (or tedious) problem set. Think about how appreciative we all are for libraries like Retrofit, GSON, and Robolectric. If you’ve solved something painful but necessary, think of how much good you can do for the community!
  • Code that is a unique solution to a common problem. As an example, Turbolinks Android falls into this category. It speeds up WebView performance by using a shared WebView, with Turbolinks doing all the work of requesting, rendering, and caching. That’s our unique take on solving a performance problem, but there are dozens of other ways to improve WebView performance too (caching, pre-fetching, mobile-specific views, etc.).

Step 3: Extract the relevant parts

Once you have an idea of what your library will do, it’s time to extract that code out into it’s own package and classes.

The goal here is simply to put together a rough outline of what the library components might be, and to see them all together. This also starts to put a soft delineation between your app’s code and what will eventually be your library.

You’ll need to hunt down all the relevant methods and slowly move them into new classes, most likely in a new package. Android Studio’s refactoring capabilities should make this pretty straightforward.

I’d recommend doing this in small pieces, slowly testing your app as you move things over a few things at a time.

Don’t get too hung up having it perfectly organized yet. Hell, you can even just throw them all in one giant class for now.

And definitely don’t worry about what the public interface is going to look like — method names and signatures don’t matter yet. Just do a “raw” extraction and get your app compiling and running.

Step 4: Refactor everything into a private interface

Get ready — this is going to be the lion’s share of the work!

Now that you’ve gone through the work of extracting the code into their own classes/package, it’s time to refactor everything. Update your method names, method signatures, dependencies, class structure. Refactor everything until you’re happy with how the library’s code looks on its own.

As you’re going along, keep this in mind: everything should click in your brain and feel natural.

Part of what’s great about building your own open source library is that it’s opinionated software. You want it to serve you and other likeminded people. So building the library in a way that fits your brain is the first step toward making a great public interface (the next step).

Beyond doing the pure plumbing of refactoring, you’ll want to gut check how your library’s interface feels in the context of your app.

If you’re on the right track, you’ll get good vibes about how the library integrates into your app’s code — readability, clarity, and the convenience it brings will all feel very natural. If it doesn’t, it’s time to go back and refactor some more.

This is also an excellent time to solicit as much feedback as you can from other programmers, regardless of their language preference. Some of the most valuable feedback I received was from Rails and iOS programmers. Iterate your code and create pull requests early and often.

Step 5: Stabilize a public interface

Now that you have an interface you’re comfortable with, it’s time to start thinking about other developers.

The good news is that you’ve done 80% of the hard work already with your private interface.

The bad news is that the remaining 20% is going about making things super stable, which means repetitive, check-everything-with-a-fine-toothed-comb work. The goal is to review every last detail of the library to make sure it’s solid.

This is the time to take a final pass through everything — naming, visibility modifiers, method signatures, every object passed in or out of your library, and whatever else you can think of.

Then test, test, and test some more.

All that said, I don’t want to make too fine a point of this. While you’ll do your best to make sure you’ve covered everything, the reality is that you’ll still miss stuff. Don’t fret — it’s software, things break. We’ll understand. 😉

Step 6: Document it

Since this is so late in the game, you might have thought you’d get away without having to do any documentation — nope, it’s a necessary step!

While I can’t say writing documentation is boatloads of fun, I did find it to be super valuable when building an open source library (I’m still generally anti-comments in private app code). Here’s what you’ll need to do.

Javadocs — You’ll want to comment every single class and method, public or private. Assume that nobody has any idea what you’re doing in the library code.

To be clear, I don’t mean you should comment every line of a method — your code should still do most of the talking. But writing a Javadoc comment for every class and method will 1) help people looking at the source and 2) let’s you to generate a nice Javadoc.

Once everything is commented, generate a Javadoc and give it a read. Look for holes and things you’ve missed. Have others read it. Does everything you wrote make sense to you and to others?

README — A good Github README does a few things:

  1. It describes what the library is and does at a high level
  2. It provides clear instructions for basic configuration and getting started
  3. It provides instructions for advanced techniques or configuration for those who are interested

I’ve found the best thing is to mimic READMEs from other libraries that you’ve found helpful. Here are a few recent ones that we’ve written that I think do a good job:

Step 7: Move the library code to its own project

Now that code complete and fully documented, you’re inching your way to publishing this to the world!

Before publishing you’ll want to move all the library classes to its own Android Studio project. This ensures the library is completely self-contained, eliminating any unexpected dependencies on your app. You basically want to see if it can compile and stand on its own two feet.

Once you’ve moved everything to a new project, you’ll need to setup a dependency to that project’s files. This is weirdly tricky in Android Studio, so here’s how to do that.

In settings.gradle:

include ':app'

include ':turbolinks' // name of the module
project(':turbolinks').projectDir = new File(settingsDir, '../turbolinks-android/turbolinks') // location of the dir

In your app’s build.gradle file:

dependencies {
compile project(':turbolinks')

With those two configurations in place, the two projects are now file linked — any changes to the library files from either your app’s project or from your library’s project will update the same files.

Step 8: Publish it!

Finally, it’s time for all that hard work to pay off!

Relatively speaking this step is pretty easy, albeit a bit tedious. You’ll be publishing to jCenter, which is the default repository with Android’s Gradle plugin. You’re simply packaging up your library in a way that Android Studio understands, and in a place that Gradle already knows about.

My recommendation is to follow a combination of the three resources below. They are pretty much step by step and walk you through the entire process of publishing to jCenter.

Once you’ve done that, your library is published. Congratulations! 🎉

Step 9: Maintenance and community relations

Now that your library is public, there will be more eyes on your work — questions, issues, pull requests and discussions will crop up. This is a good thing!

I’m always thankful that people are interested in the project and want to be involved. But there will be times when you disagree with a discussion or you simply don’t have time to address everything. That’s OK!

Maintaining a library is no small task. There’s going to be some pressure from the community to keep things moving. We all want things to be better. But it’s also OK for you to say no or to defer work. There is literally always more to work on.

The most important thing is that you keep you continue enjoying working on the library. If that means addressing all the community requests, do it. If that means saying no, do it. If that means working only on the things you want, do it. Keeping your sanity and happiness working on this library will be what sustains it for the long run.

Summary & Acknowledgements

If you’ve made it this far, you’re well on your way to launching your own Android open source library. You’ll soon be helping a lot of people by making their lives easier and their work better. Great job! 👏🏆

If you have questions about anything I wrote about or just want to chat, I’m always glad to help! Feel free to email me or hit me up on Twitter.

Also, this process is the furthest thing from a one-person show. Literally none of what I talked about above — creating the actual library and having the opportunity to do so — would have been possible without the help and encouragement of everyone at Basecamp. Thank you all!

I’d like to thank a few specific folks for their unwavering support and contributions in helping launch and maintain Turbolinks Android: Jay Ohms, Jamie Dihiansan, Sam Stephenson, Jeffrey Hardy, and Zach Waugh. ✊

See Turbolinks Android in action in the Android app for Basecamp 3!

If you found this article helpful, please do hit the heart button below and let me know on Twitter. Thanks!

The most helpful thing you can say to a teammate: “It’s your call”

Great people blossom when you nurture them with trust and respect

When a teammate asks me a question, one of my favorite responses is “It’s your call.” It’s such a simple yet powerful phrase. In just a few words it conveys…

Trust | Confidence | Respect | Autonomy | Ownership | Empowerment | Responsibility | Decisiveness

How can such a simple phrase mean so much? Take this common scenario — a team discussing what to work on next. Here’s one version of that conversation:

Julie: What should I work on next?
Shelley: How about a native homescreen?
Melissa: I’ve always wanted breadcrumb navigation!
Sara: Another option would be to squash some 🐛
Erica: File upload feature would be cool

Now there’s absolutely nothing wrong with a back and forth like this. Julie has opened the door for feedback, and the feedback provided makes total sense.

But imagine the same opening line with a single response:

Julie: What should I work on next?
Shelley: It’s your call 😀

Immediately the whole tone of the conversation has changed for the better.

Instead of asking for permission and being given specific directions, Julie has been empowered to make the decision herself.

She now has complete ownership. She’s free to explore and make her own choices. She’ll assess all the open tasks. She’ll drum up her own new ideas. She’ll decide what’s next based on her own criteria of importance.

More importantly the team has expressed sincere trust, confidence, and respect in her and her abilities to do everything. They’ve said “whatever you decide is cool with us.”

Full autonomy like this has significant long-term benefits to teams —no managers, increased motivation, time saved, sharper assessments, faster decisions, happier people, improved independent learning, better teamwork and so much more.

All of that accomplished by just saying a simple phrase.

When it comes to software development, conversational opportunities like this come up pretty frequently. Keep an eye out for questions about:

  • What to work on next
  • How to implement a feature
  • What tools, APIs, or libraries to use
  • How to manage/keep track of work

Of course when you’re asked for your opinion, you can certainly give it — you don’t want to leave people completely hanging.

But before you do that, consider challenging the person asking the question by simply saying “It’s your call.” You’ll be pleasantly surprised by the outcome, and the long-term benefits are well worth it. 🤘

Great things can happen when you emphasize these values — Basecamp 3 and its Android app are the result of a handful of autonomous teams working in an independent, yet highly coordinated environment.

If you found this article helpful, please do hit the heart button below and let me know on Twitter. Thank you!