Make the most of limited coding sessions
Writing an app in your spare time is difficult. Spare time is a luxury that many of us have little of. Opportunities to work on your app are few and far between, and sometimes you can go long periods of time without being able to sit down and focus on your app. Drawing on my experience as both a spare-time developer and professional engineer, I’ve refined my process for getting the biggest bang for my buck out of my spare time hours, and I’ll share some of my tips with you in this article.
There are many reasons you might be writing an app. It could be for fun, to learn new skills, or to create a portfolio. It could be a side hustle, or you might be bootstrapping a new business. If you’re really lucky, it could be all of those things. Whatever your motivation, the key to faster results boils down to these principles:
- Make the time you have as productive as possible.
- Remove the need to remember anything from one session to the next.
- Keep sight of your goal, and keep moving towards it.
In the rest of the article, I’ll share some practical suggestions that will help you achieve these.
This article assumes that you can already code. If you can’t, there are lots of great resources to help you learn. Read and bookmark this article to give yourself an idea of tactics you can use in the future, but don’t worry about your process. For now just focus on learning and writing code for your chosen platform.
Keep a list of tasks
Having a list of tasks means you always know what features and tech changes you are intending to make. When you get time to work on your app, you can pick a task from your list and work on it.
Your list can be as hi- or lo-fi as you want it to be. It could be a simple list in a notebook, post-it notes on a wall, a project in a task manager app, such as Things or Omnifocus, or something more heavyweight like Jira. Currently, I find that a simple Trello board works best for me.
Something I like to do is mark tasks on my list as ‘easy’ when I know they won’t require much time or concentration. Then if I haven’t got long, or if I don’t feel up to a difficult challenge, I can still pick something from my list and be productive.
Make your tasks as small and self contained as possible
If your tasks are small and self contained, you can start them, complete them and release them in the shortest possible time. This is good, because every time you complete a task, you are moving towards your goal. If, on the other hand, your tasks are big, or tangled up together with other tasks, you’ll start things but find it difficult to finish anything. This will also be the case if you start new tasks before finishing previous ones. You’ll have lots of complexity to remember and manage, and you’ll struggle to release updates to your app.
Write lots of tests
Unit and UI tests are invaluable when you’re writing an app in your spare time. Having good quality, automated tests across your project allows you to make changes with confidence. You will save time that you might otherwise have to spend manually testing your app (although I’d always recommend spending some time manually testing), and you’re less likely to release bugs. And you won’t need to remember how your app works or what needs testing between coding sessions.
Use source control and commit at the end of every coding session
Source control has lots of features you can leverage, such as the ability to create new branches for different features, visibility of what changes you made when, and if you use versioning and tags, you can match up exactly which code you released in which version of the app. You can read more about versioning and tagging in my article here.
But, for me, the real advantage of using source control comes from getting my code to a state where I can commit to source control at the end of every coding session. It takes a bit of practice to line things up, but it means that the next time you work on your project, you’re starting from a clean point. You know that everything you worked on last time was finished and tested, so you don’t have to spend any effort working out where you were up to, and you can hit the ground running on your next task.
Release every time you finish a feature
Releasing every time you finish a feature is a great strategy for several reasons. Firstly, it keeps your releases small, therefore lower risk. Secondly, it means that you don’t need to remember what you’ve added since the last release, and work out if it’s tested and ready to go. Code it, test it, release it, and you don’t need to worry about it again. And thirdly, it keeps improvements coming through to users, it keeps turning your hard work into tangible outputs, and it keeps you moving towards your goal.
Some of the other tips help you release every time you finish a feature, i.e.
make your tasks as small and self contained as possible,
write lots of tests, and
automate releases. To lower the risk of releasing to users too soon, I release a beta version first that I use for a few days. Once I’m happy with it, I push that same version to the app store.
You can read more about why it’s good to release early and often in my article about release strategies here.
Don’t work on anything straight away
As I’m working on my projects, I often have ideas for things I’d like to add to my app. It’s tempting to jump straight in and start work on them. However I’ve learned that it’s more effective to take a note of them and come back to them later. If they still seem like a good idea after a couple of weeks, I’ll prioritise them. Often though, I’ll find they don’t seem important any more, so I’ve saved myself from wasting time on them.
The same goes for suggestions from other people. It’s valuable to get feedback on your app, but people will have different opinions on how your app should look or work. It can be easy to overreact, especially to negative feedback. Take a note of their suggestions and come back to them later, when you’ll be able to make an objective decision about any changes you want to make.
Fix things that slow you down
Whilst it’s important to keep focused on tasks that take you towards your goal, it’s useful to find and fix things that slow you down. Removing friction and fixing bottlenecks in your process will allow you to go faster, and squeeze more out of your time.
For example, I’ve been working in SwiftUI on a view that contains lots of images. The previews were struggling to render, meaning I had to run the app in a simulator to see what it looked like. This was slow and frustrating. I spent a coding session fixing it, by adding code to shrink the images in previews, allowing them to render. Whilst I wasn’t any closer to my goal after that particular session, every coding session I’ve had since has been more productive, allowing me to get features completed faster.
The more automation you have, the easier and quicker it is to release your app. I use Fastlane to automate all the things. I run everything locally, because it’s simple and free, but there are other options available that allow you to build scripts in other ways, and to run Fastlane remotely, including Bitrise, CircleCI, GitHub Actions and Bitbucket Pipelines.
I have the following scripts (or
lanes in Fastlane terminology):
beforePullRequestwhich I use to build, test and lint a branch to check it is ready to merge into my main branch.
releaseBetawhich tests my code, increments the version number and adds a git tag, then builds an archive and uploads a beta release.
snapshotwhich loads test data, then takes screenshots which I can upload to the store.
releaseToStorewhich prompts me to complete any manual steps required for release, such as writing release notes and updating meta data, creates an app version on the store, uploads meta data and screenshots, adds my chosen build to the version, then submits it for review.
Automation is great for three reasons. Firstly, it saves time. I can release as soon as I’m ready, because it only takes a few minutes, and doesn’t eat into my development time. Secondly, it removes opportunities for me to make mistakes. Thirdly, I don’t need to remember what to do. I can come back to my project after a few weeks or even months, run my script, and let it take care of all of the steps for me.
Release to users as early as possible
With my first spare time app, I wanted everything to be just right before I launched it on the store. That took a lot of time and effort. Now I release as early, and as often, as possible. With my latest app, Windsurf Caddy, I released it to the store with only basic functionality and styling.
At first read, that might not sound like a great idea, but here’s why I’d recommend it. Firstly, it turns your hard work into a tangible output, and keeps you moving towards your goal. Secondly, it helps you get over the fear of sharing your work with other people. If you release before it’s perfect, you don’t need to worry about it being perfect. You can improve your app with every subsequent release. And thirdly, it focuses you on what to add next to most benefit your users, and it motivates you to keep releasing updates.
Leave yourself a trail of instructions
When working on an app in your spare time, you often have long gaps between coding sessions. This makes it easy to forget what you were working on, or how something was implemented. I’ve learned to assume that I’ll have no memory of a project next time I pick it up, so I leave myself a trail of instructions, positioned strategically where I’ll need them. Here are some of the things I leave myself instructions about, and some of the ways I document them:
- Comments in the code describing what something does and why it does it. This saves me working it out again in the future, or worse still trying to ‘fix’ a piece of code, only to re-learn the hard way why it was the way it was.
- I always aim to commit at the end of a coding session. However if for some reason that isn’t possible, I leave TODO comments in the code to tell me exactly what needs finishing off. I also write notes in my task list telling me the branch I was working on, and linking to any references I was using or any notes I had made.
- I add a
readmeto my project that tells me how to run it, where the repository is, details of any accounts I need, e.g. for the app store or analytics providers, and where to find any scripts for creating test data or releasing the app. This means I can get up and running again quickly, even after a long break from the project.
- I document my release scripts with clear information about what the scripts do, and when they should be used. I also set up my scripts with user prompts so they remind me to complete any manual tasks as they are running.
Take the time to learn the skills you need
There are lots of skills needed to write an app. You need to be able to code, and you need to be familiar with the tools and SDKs you are using. You need to learn how to build your app for the store, and how to create screenshots and marketing materials. You might find yourself building a website for the app and using tools to design your UI. It can be tempting to skim through articles and hack together what you need without diving too deeply. Often though, I’ve hit a point when I needed to learn what I was doing properly. Whenever I have, I’ve wished I’d taken the time to learn it properly in the first place, as I would have been more productive overall.
Avoid the temptation to refactor
My coding style evolves over time. I can look at code that I wrote just a few months ago, and find it jarring. I might have a new, preferred way of structuring code or solving particular problems. It can be tempting to refactor the code to use that new style, but if you do this every time you work on the project, you won’t make any progress towards your goals.
There are a few ways to decide whether it’s worth refactoring. Firstly, follow the rule of
never work on anything straight away. A couple of weeks later, you might realise it’s not important. Secondly, ask yourself if there was there a problem with the old way of doing things. If it didn’t work properly or had potential bugs, there’s a strong argument for making the changes. Thirdly, would the refactor make your code more testable and / or maintainable? If so it might be worth making the changes, but maybe not until next time you work on that code. Finally, are the changes just to make the code look better? In that case, your time would be more effective spent making changes that will take you closer to your goal.
If you’re a developer by trade, you might have noticed that many of these tips are similar to practices you’d use in a professional environment. It stands to reason that when you’re spending your own time and resources, you can get the best bang for your buck by using the same methods as those tried and tested by commercial teams. This is great on two counts. Not only does it make you more effective in your spare time, practicing these techniques and developing a feel for how they work will help you to become more effective and more valuable in a professional capacity.
Blog originally posted on Medium and can be found here