Have you tried coding a side project? If so, how’s it going? If you’re like me, you’re not trying to get rich from your side project: you just want to have fun building something cool. But even that modest goal can be hard to achieve.

Maybe your side project never seems to get to the point that it’s useful, no matter how many hours you put into it. Or maybe you’ve been pulled away by the priorities of life. Or maybe you struggle to keep up motivation to work on the project.

I can identify with all these challenges. But somehow over the last few years I’ve managed to create a suite of tiny productivity side projects that I use every day. They make my life better, keep my programming skills sharp, and are something I can point to for some indication of the kinds of programming skills I have. For me, that’s side-project success.

How did I manage to create these apps? I don’t have more talent, motivation, or free time than other developers. But over time I stumbled across a few tips that helped these side projects go more smoothly. Hopefully what I’ve learned along the way can help you with your side projects, too—whether you’ve never tried building one, have tried and stalled, or are making progress.

My Projects

I’ll reference my own side projects as illustrations for each tip, so let me introduce them:

iPhone showing a form for editing a todo task

Surely is a to-do list that’s usable both on the web and in a native mobile app thanks to React Native Web. The backend is a Rails API. “Yet another to-do list app? Surely, you jest!” I built my own to-do list app to tailor the user interface (UI) for the way I manage todos—and to leave out features I don’t use that clutter up the interface.

web browser showing a page titled 'npm' with notes about usage and development

Slapdash is a place to write and share quick topical notes. Each page corresponds to a topic and is publicly-readable with an easy-to-remember URL so it’s easy to share. It uses a web-based editing interface instead of something git-based so that there’s no “publishing process”—you just write your note and then it’s live. It’s implemented as a Rails server-rendered webapp.

web browser showing a page titled 'tag: mac-gaming' with several links to web pages on the topic

Firehose is a link-saving app with a React frontend and Rails API backend. I track any interesting links I find there—especially software development articles and videos that I consult regularly. I had been keeping these links in a proprietary app, but they’re so important to me professionally that I wanted to move them into a system I control.

terminal window running a Rails console with two Link records shown, which each define a domain, slug, and destination

Shorten_rb is a link shortener implemented as a Rails API. I wanted a way to set up short links that will redirect people to longer URLs so that I could easily share them at workshops and on live streams. Commercial link-shortening services are expensive, especially if you use your own domain name.

Surely and Slapdash are completely free to use with open registrations, so feel free to sign up if you’d like to try them out. Firehose and Shorten are single-user and require you to set up your own instance to use them.

Now let’s jump into the side project tips I discovered while building these apps.

Tip 1: Build for your own use case

Well-known commercial and open-source software is often jam-packed with features, configuration options, or extension points to satisfy every imaginable use case. It’s tempting to assume this is an essential part of “good” software—but I would challenge that assumption.

An app with fewer features is better if it’s the only one with a feature you need. I added two such features to Firehose: a field to record the source of a link (a name or URL) and a field for comments about the link. I wasn’t able to find these features in other link-saving apps. Some reading apps have a feature that on the surface seems “better” than a single comments field: the ability to add comments to multiple highlights throughout a page. But this more powerful feature is actually worse for my use case: it’s more work to highlight a random bit of text when I really just want to leave a comment about the whole document.

Another situation when you might prefer an app with few features is when additional features actively cause a problem. For example, many to-do apps make it easy to organize lots of to-dos—but this tempts users to keep an overwhelmingly large list of tasks forever. The goal shouldn’t be to manage to-dos; it should be to complete them. In Surely, I didn’t add any bulk-edit features that would make it easy to keep lots of to-dos around. Instead, I have to deal with one to-do at a time, which steers me to clear those todos off my list by completing or deleting them.

An app with fewer features is also easier to maintain. When I ported Firehose from React Native Web to React, I was able to finish in a weekend because I had limited it to only a few screens.

Tip 2: Build with high-leverage technologies

What makes a technology the right fit for your side project? Not necessarily popularity or whether it is “webscale.” Instead, ask yourself these questions:

Is this technology something you already know or are motivated to learn? Side projects can give you an opportunity to try something you aren’t using at your day job. And your motivation is doubled when the payoff is both the thing you build and the things you learn. But learning as you go will slow your progress. Slow progress can sometimes lead to a project fizzling out. Assuming you may not be able to have both, decide which is your top priority: getting it built or learning something new. Prioritize accordingly.

Is the technology well-supported? Does it have good documentation, and does it receive timely updates for security and compatibility? For some folks, part of the fun of side projects is figuring out bleeding-edge technologies and contributing docs and fixes. If that’s not your interest, though, it will be easier to ship your side project if you’re using technologies where the docs and maintenance process are well-established.

Is the technology high-leverage? That is, does it allow you to get right to building the features you want to build, or do you have to do a lot of low-level work as well? I keep coming back to Ruby on Rails for APIs because its built-in functionality and rich ecosystem of mature libraries allow me to focus on my user-facing features. But there are other high-leverage approaches, too, depending on your experience. For example, Jason Lengstorf shared how frontend developers can build full-stack apps by relying on API-driven tools.

Does your project have the problems that this technology solves? I’ve looked into a number of other technologies, including Async Ruby, Express, CouchDB, Elixir, and Crystal. I hope to try out all of them in the right context, but my side projects are not it. My projects are low-throughput, I/O-bound CRUD systems with a very small number of users. The advantages that Ruby on Rails provides for systems like that, plus my familiarity with Rails, mean that for these projects those other tools will only be more effort for less reward. But, of course, your project’s needs may be different.

Tip 3: Build with technologies you can change

Ideally you won’t need to change your side project’s technologies much over time, but sometimes new technologies are a better fit or old technologies are discontinued. To prepare for this, choose technologies that lower the effort needed to change in the future.

The main way I’ve enabled change on my side projects is by separating the frontend and backend, setting them up to communicate with JSON over RESTful HTTP endpoints. This separation has made it easy for me to rewrite the frontends in different technologies. A new frontend doesn’t need to reimplement data storage and authorization: they are already implemented in the backend. No data migration is needed because the backend stays the same. This allows me to start using a new client as soon as I finish building the most important feature, getting an early feel for the new technology. When I need a secondary feature, the old client is available for me to fall back on—and I make a note to prioritize building that feature next.

GraphQL would be another way to achieve this frontend/backend separation. There’s one restriction GraphQL would place, though: I would only be able to build on platforms with well-supported GraphQL libraries.

Separating frontends and backends has also allowed me to experiment with swapping out backend technologies. At one point I tried replacing the backend of Surely with CouchDB for automatic syncing. The fact that I could reuse my existing frontend lowered the effort for me to try this experiment. I ultimately found data inconsistency issues cropped up that weren’t worth troubleshooting for my side project, but the low effort of the experiment meant I didn’t feel bad reverting to the old RESTful backend.

With Shorten, I was able to avoid building a user interface entirely! End users don’t need an interface: they navigate to the short URL and are redirected to the destination. And instead of an admin UI, when I need to create a link I just connect to the Rails console on my production Heroku app and run a command to insert a record. If I decide in the future that I need a UI, I can add RESTful endpoints to the backend and build a frontend—but I can defer that work until it’s necessary.

Tip 4: Don’t worry about consistency

In case you haven’t noticed, my side projects are a bit of a mishmash. Each of the four has a different frontend: React Native Web, React web, Rails server-rendered pages, and no UI. Two of the projects have open registrations for multiple users (Surely and Slapdash), while the other two require setting up your own instance.

Having projects on a variety of technologies can make them harder to maintain. For example, at one point I had frontends built in React, Vue, and Ember, which meant three times as many breaking changes and three times as much research to fix them. So I’ve consolidated technologies when it makes sense to do so.

But the mixed state of these projects is part of the beauty of them. Why do they need to be consistent? I’m not trying to convince more people to install them, or to hire people to maintain them, or to get attention from any particular programming community. I’m trying to make useful apps, and the only reason I need to change one of them to be more consistent is if it helps achieve that goal.

Success is what matters most to you

These four tips will help your side projects be more successful—where I define “successful” to mean making steady progress building something useful, learning, and having fun. I’d like to end with a qualification and a note about success.

First, the qualification. People’s life experiences are not the same, and that affects the cost and benefit of doing side projects. Maybe work or family responsibilities mean you have less free time or energy than others. Don’t feel bad if you want to put in your 40 hours and then close your code editor for the week. And for goodness sake, in a pandemic, do what you need to do to feel okay and get through it all! Side projects are an option to consider if and when it fits.

Finally, about success. Shannon Vallor recently published the article “We used to get excited about technology. What happened?”—it’s worth reading in full. Consumer tech used to be focused on building helpful and enjoyable products, but now it’s more often about gathering data for monetization regardless of the impact on the user. In this atmosphere, side projects are a breath of fresh air because just about the only reason to build them is to help someone. I hope you get to work on a side project, you get some help from these tips, and you have a blast.

If this post was interesting to you, the talk “The Selfish Programmer” has more thoughts on the benefits of writing software for yourself.

Josh Justice

Person An icon of a human figure Status
Sleeper Agent
Hash An icon of a hash sign Code Name
Agent 00155
Location An icon of a map marker Location
Conyers, GA