How I built a multi-platform app
It was a warm night in late 2014. My day job hadn't provided me with any value outside of paper money in several months, and I was getting the itch to build a completely new thing. In recent months I'd heard my boss talk about Go (golang for you search engines) and how nice it was. I knew PHP, but had recently found Node.js in my last product, LunchTable, unrewarding. So a new backend language to learn appealed to me.
I've also loved writing for a long time. I never planned to make Yet Another Text Editor, but around this time I'd noticed how many people were using pastebin.com to essentially blog. Medium was also the hotness du jour, so I thought, what if I made pastebin look good?
I started thinking of names, avoiding the -ly's and .io's and eventually found a plain-English domain name that couldn't have been more perfect: write.as. Here you would write as any kind of person you choose; you would be free from creepy surveillance and could be yourself. I registered the domain that night.
By the end of January I had sketched out the basic feature set, but was still unsure about what to do first. On some Thursday night while I was reading about actually building this future web application, I found an article on building a telnet server. I thought, that'd be a fun thing to do tonight. So I did.
After a few nights of hacking the server together I ran it... and it worked! I could locally telnet in, type something, press Ctrl-D, and it'd save that text to a file. I'd only have to add a web server pointing to the directory where those files were stored and I'd have my MVP. So I replaced Apache with nginx on one of my VPSes, threw the web application up on nerds.write.as and shared the URL with the first audience I thought would appreciate it: /r/linux.
First users: reddit
I immediately saw comments and upvotes on my post (titled with all you needed to know: telnet nerds.write.as
[note: only half-working now shut down after repeatedly getting DDoS'ed]). One of the first commenters asked if it was open source, and I thought that'd be fun to do. So I created a GitHub organization and added my first repo. People published over 400 posts that day.
Some people tried things like piping command-line output to the telnet service, but it didn't work. So within 24 hours our API was born to support this.
First API
In the spirit of sprunge.us, I set it up so you could POST
to Write.as with short parameter names, and the API would return the URL where you could find your new post along with a unique token you'd only see once. This is what you'd use to later edit and modify posts.
This simple API would serve all early Write.as 1.0 clients.
First platform: Android
My salary at the time funded an Android app for a now-defunct startup — and I've always been an Android user — so I decided to build an Android app next. I used my initial sketches to guide the functionality I'd need. After about a week, at around 9pm on some Sunday in February, I pushed a build to Google Play.
At 10:30 I pushed a bug fix.
The next morning I submitted it to /r/androidapps and /r/goodguyapps (it was one, after all) to decent success. I released the app on the Amazon/Kindle store and didn't get many downloads. It doesn't seem to be a good platform for discovery.
Then I learned about ARC.
Second platform: Chrome OS
Around this time, the Chrome team was looking at bringing Android apps to Chrome OS with a tool called the Android Runtime for Chrome. Since I had an Android app that worked well, I figured what the hell? and with little effort ported it to Chrome OS.
It turns out there are a lot of users on Chrome OS, and they seem to be starved for apps. But this turned out to be our best platform, giving Write.as a ton of visibility, and growing faster and retaining more users than any other.
Third platform: command-line (cross-platform)
By April I still had the “Pastebin meets Medium” product mentality that I'd formed at the beginning. I still thought I'd made a prettier pastebin, and though I had grander plans for the product, I found it hard to spout marketing gold that could hook any user who had never used a pastebin. So I released a client pastebin users would love: a command-line interface.
I also built this in Go, since it could run across platforms from one codebase. It was simple and programmer-oriented, so I open-sourced it and eventually hosted the binaries on GitHub. I named the first version 0.1 because for some reason I assumed it'd need a lot improvement.
Turns out the first few versions were fine.
Fourth platform: Chrome extension
I can't remember what prompted me to think about a browser extension. It could've been one user mentioning it, or me simply stumbling across the documentation and realizing how simple it was to build. Regardless, shortly after launching the command-line utility I started on the Chrome extension.
Still not forgetting my pastebin roots, I registered the paste.as domain and carried the name to a new Chrome extension. The extension would post any text you'd selected in your browser once you pressed Publish, or let you type into a small box in the upper corner of Chrome. I released it at the beginning of May, and it holds about a steady 200 users.
Fifth platform: iOS
By the summer, several users had requested an iOS app. I personally didn't care for the iOS platform or its approval process or the $99 I'd have to pay annually to release a free app. But I wanted Write.as to be on every possible platform — and I had built a good model in the Android app — so I started preparing for it.
I hadn't done any serious iOS development in two years, and I was more focused on next steps for the product and closing out my tenure at my day job. So I spec'd out the iOS app based on the Android one, hired an iOS developer on freelancer.com who knew his iOS paradigms, and after 2 weeks of communication in early June we released Write.as for iPhone and iPad.
I promoted the app on the various iOS subreddits and seeded a decent user base. Initially it got a ton of traction via the App Store and grew quickly — much more than the Android app did. Though it eventually evened out, and despite the innumerable writing apps on the App Store, people still seem to enjoy it.
Sixth platform: web
In the natural course of me doing what was new and interesting, Write.as went 6 months without a real web application. Designing complex applications for the web was never my strong point; this probably had the most to do with it. But in September I decided to build one.
Up and through this time, Write.as was fully anonymous. It never supported user accounts, and the data for further interactions — that special one-time token — was simply stored on the client device. The same feat was easily accomplished with localStorage
on modern web browsers. And when you're dealing with plain text, turns out all you really need is a textarea
.
I've always kept nothing more than a basic working knowledge of JavaScript in my tool belt. I used jQuery on my heavier web apps in the past and got pretty far. But I thought it'd be crazy to have an editor with minimal DOM manipulation and an occasional XMLHttpRequest
load a library like jQuery. So I stuck with vanilla JS and an uninteresting helper class I wrote myself to save some typing.
By the middle of September Write.as was hosting 2,000 posts. I put the web application / writing space on a hidden URL and tweeted it out. Like the command-line interface, it was bare-bones and “experimental,” but again turned out to work fine.
In June 2016 our 2.0 features (blogs and accounts) came to the web first. From what I hear, most people prefer it to our other clients.
In six months I launched Write.as on six total platforms — most of which came with built-in stores that helped people discover my new product. But each also allowed me to seek out communities of users on these platforms looking for new tools, and to gather their feedback.
A few things contributed to the app's success on each platform. First, I took a slow, deliberate, release when it's ready approach to each new platform. This meant a more stable app once it was out in the wild and the chance for me, the mostly-sole developer, to stay on top of a growing user base. But it also let me tailor the app towards each platform. The Chrome extension, for example, lets you quickly highlight and publish text from the web. The command-line interface includes more flexibility, since it serves the type of users that regularly work in a terminal window. The mobile apps are native, generally following each platform's UI / UX paradigms, and as simple as possible for someone who might, for example, do most of their computing on a touchscreen.
But having so many platforms to support eventually became a stumbling point as I worked on Write.as 2.0. Maintaining the complexities of all the existing and new clients severely slowed me down over the several months I spent building the new back end. I wanted to remain forever backwards-compatible, supporting new and old functionality alongside each other. My goal, after all, was to augment already useful features — not replace them. This resulted in an unconventional API where version 1 still resides at write.as/api and version 2 lives on top in RESTful endpoints like write.as/api/posts and write.as/api/collections.
It also meant eventually having users looking to these other platforms wondering where new functionality is while I gradually update them. The previously-stellar Android app rating has suffered, for example, simply because people aren't seeing all the functionality they want. But I knew waiting to release everything at once wasn't necessary. People are very resilient when they see software they like, and won't be stopped from fully utilizing what's already out there, or even from becoming paying customers. Ultimately this approach was right for this product. It's built as a utility, aimed at doing one thing well. Software like that should live on multiple platforms, and can even be developed by (essentially) one developer.
If you're a developer who's ever thought about doing something similar, know that it can be done. You can only build for the web or the Apple ecosystem and make it pretty far. But there are still hundreds of millions of people who need good software that works offline, or on reasonably priced devices. Above all, there hasn't been a better time to build software that reaches people on the myriad devices and platforms in the world. The tools, languages, and runtimes are all there, if only you'll use them.