Resuming work on a stale project

MP #11: We've all been there, but there's a lot you can do to get back up to speed.

Sooner or later, every programmer finds themselves in the following situation: you started a project that you were really excited about, made some initial progress, and then something came up that pulled you away from the project for a while. When you finally found time to get back to it, you felt totally lost. How do you start working efficiently again? How do you recapture the energy and focus you had the last time you were actively working on the project?

Status bar from GitHub showing the last commit was made 12/19/22.
I never intended to take a 3-month break from this project!

This is a really common situation, and one you’re likely to experience throughout your life as a programmer. Fortunately, there are a number of things you can do ahead of time to make this situation manageable. And when you find yourself lost, there are a number of strategies for getting back up to speed efficiently.

You’re not alone

This post was inspired by a question I saw recently on a Python subreddit. It’s one that’s been asked repeatedly over the years in every programming forum, and one that readers have frequently written to ask about as well. I always relate to people asking this kind of question, because it brings up such a familiar feeling. I can feel the excitement people have for their projects, and the new energy and focus they’d have if they could just get back on track.

When you find yourself in this situation, please know that you’re not alone. Unfortunately, much of the advice that’s offered when these questions come up isn’t nearly as actionable as it should be. Telling someone who feels lost to start over again, or “just read the code”  doesn’t really give them a specific path back into their project, and more importantly back into that state of flow they remember feeling.

Proactive measures

If you’re currently working on a project, there are a number of things you can do now that will make it easier to pick up work at any point in the future. It’s nice that most of these thing aren’t just extra tasks; they’re steps that will almost certainly improve your current workflow as well.

Write some documentation

The suggestion to write documentation scares some people, because they immediately think of the thorough documentation they’re familiar with from popular libraries. But you don’t need to go that far to set yourself up for success. If you have no documentation outside your code files, a one-paragraph readme outlining the specific purpose of your project can help you recover a sense of purpose and focus when you’ve become distanced from the project.

Directory from a project on GitHub showing multiple documentation files.
Most of my private projects that will never be made public still have a docs/ or my_docs/ directory.

There are other kinds of documentation that tend to be easy to write when you’re actively working on a project, and really helpful for resuming work at a later point:

  • How to set up and run your project on a new computer;
  • How to add a new feature to your project;
  • How to run tests against your project.

You also don’t need anything complex to get started with this kind of documentation. Make a new folder called my_docs/ in your project, make a single file called initial_documentation.md or README.md, and dump what you know about the project into that file. This will be really useful when you come back to the project, and makes it much easier to start writing formal documentation whenever it becomes appropriate for the project. This kind of information is also the first information you’d want to share if you get to a point where you want to open your project to potential collaborators.

Open some issues

I’m a huge fan of GitHub’s issues. I know there are more complex ways to manage larger projects, but I’ve found a simple set of issues to be a really good way to capture my thinking around a project as it’s evolving. The following steps can give you a set of issues that make it easier to maintain your current state of focus on a project, and make it easier to resume work later when you inevitably get interrupted:

  • If you have no issues, write one called Current Tasks. Anything you think of that needs to be done “when you get a chance” can be dumped to this issue. Checking these boxes feels good during active development, and every empty checkbox is a potential pathway back into the project after you’ve stepped away from it for a while.
  • Add some labels. Make sure some of your labels are appropriate for resuming work after some time away. Labels such as small_task, minor_bug, and refactoring_work are all good paths back into a project.
  • If you know you’re going to step away from a project, a specific issue with a name like Start here can be really good. Write down all the things you’d want to do if you weren’t about to get interrupted, and pick up here whenever you can.
A GitHub issue banner titled "Pausing this work #93".
Sometimes a “Pausing this work” issue just contains the highest-priority tasks to return to. It may also contain a list of unrelated tasks I have to finish before coming back to the project.

These kinds of issues don’t just point you to appropriate tasks when you come back to a project. They also help bring you back to the mindset you had when you were last actively working on the project.

Write a single test

Having even a small set of tests has a number of benefits for your projects, even in early stages of development. In fact, writing a single small test removes the friction of having to set up a test suite later. It’s much easier to add a test to an existing test suite, than it is to write the first test. If you haven’t already done so, consider taking ten minutes to write your first test now.

When you come back to your project later, this sets you up in several ways for easing back into the project. You can run your test suite, and know that things are still working. You can resume work by writing a test for an untested feature or behavior of the project. Writing tests is very safe; you won’t break your project by writing a bad test.

It’s also worthwhile to write a list of tests you want to implement for your project. Checking items off this list is a very satisfying, meaningful, and approachable way to step back into a project. It’s also worth a few minutes to document how to add to your existing test suite.

Section of a GitHub repository showing a small set of unit test files.
In the early stages of a project, don’t aim for 100% test coverage. Write enough tests that you feel comfortable trying new things in your codebase, without worrying about breaking parts that you know are correct.

Resuming work if you’ve done any of this

If you’ve done any of this background work, there are a number of ways to get back into the mindset and flow you had when you last worked on your project.

Open a Resuming work issue

Open an issue whose sole purpose is to carry you through this transition back into the project. Write a few quick goals related to any of the suggestions that have been discussed here. Record any questions you have, even one as simple as How does this ?*&^ thing work?! Keep this issue open until you’re back to the level of understanding and efficiency you had before. If you go through another period of stepping away from your project, notes from this issue can be quite helpful.1

Run the project

If you haven’t done so already, run your project. Does it still work? Have you changed anything about your local environment since you last ran the project? If so, make notes about this in the Resuming work issue.

Run your tests

If you have a test suite, go ahead and run it. Even if it’s just a few tests and they all passed last time you worked on the project, seeing the suite pass is quite grounding. Seeing a small test suite pass is also an invitation to add a few more short tests. And if any of the tests don’t pass, you’ve got something to dig into right away, with a very specific purpose.

Complete any single open task

You don’t have to close a whole issue. Just look for any open task in any open issue, and try to check that box. You’ll get the satisfaction of completing something, and be one step closer to closing an open issue. Feel free to go through a few tasks across a number of open issues, until you have the clarity back that lets you know which issues to focus on more fully.

Resuming work if you haven’t done any groundwork

If you haven’t done any of the groundwork described above, and all you’ve got is some code files, you’re still not in a bad position. You’re starting from a blank slate, which gives you some flexibility in how you get back into the project. Choose from any of the following suggestions, and keep going through them until you have a reason to focus on something else.

Push your code to an online repository

Whether you prefer GitHub or GitLab or something else, consider pushing your project to an online repository. If you have to step away from your project again, you can rest assured that your project is backed up to an online service. Most online code hosting platforms also have integrated issue trackers, which helps with the next point.

Open an issue

Open a new issue called Resuming work, as described above. First list the tasks you wish you’d done earlier. What would make you feel better right now? Having some documentation? Having a test suite? Either add those to your Resuming work issue, or open dedicated issues if some of these are likely to be longer-term tasks.

Jot down any questions you have about your project, and any steps you know you need to take but haven’t written down anywhere. Start capturing your thoughts about the project as they come, because they’ll come quickly as you get back into the project. I often make an issue called Parking lot, which is a general dumping ground for any thought that comes up that I don’t want to lose, but which doesn’t fit neatly into another category.

Write some documentation

At the very least, write a short README.md file. Write a one-paragraph summary of the project, covering its purpose and motivation. Focus on why you’re building the project and what it does, and less on how it works. If it feels helpful, add more sections that do cover how the project works.

Consider writing a Getting Started guide, either focused on yourself, or focused on others if you’re planning to make the project public at some point.

Write some tests

If you don’t have any tests yet, write one test. Either write a small test that’s quick and easy, or write a test that encompasses the overall output of your project. A small test gets you started on a suite of unit tests. A comprehensive test tells you that whatever changes you make to your project, it’s still doing what it’s supposed to overall.

If you’ve never written tests before and you want to develop your project further before writing tests, consider starting a list of the tests you’d like to write. What aspects of your project’s behavior are already correct? That list becomes the set of tests that you should start with. If you’re new to testing, the pytest Get Started page is relatively accessible.

Run your project

If you haven’t done so already, run your project. Does it still work? If it doesn’t, can you troubleshoot the current issues? If troubleshooting is difficult, can you recreate the conditions when it last worked, and slowly update things until it works again?

Some of this depends on how much your system has changed since you last worked on the project, and how much the libraries your project depends on have changed as well.

Update your dependencies

There are a number of things you can do if it’s been some time since you last ran your project, depending on how many dependencies it has:

  • If you’re using a virtual environment, rebuild the environment using the latest version of Python. Debug any issues that arise from using a newer version of Python.
  • Update your dependencies, one by one. If your project has multiple dependencies, update each one and make sure your project still works. This can be more manageable than updating everything, although in many projects it can be reasonable to update everything at once and see how much of your code needs to be revised.
  • If you’re not using a virtual environment at this point, consider using one so that your development environment is easily reproducible. This will help you as you continue to develop the project over a longer timeframe, and help anyone who contributes to your project as well.
A short requirements.txt file from a Django 1.3 project.
This is the oldest Django repository in my GitHub collection, and I still might return to this project someday. If I do, one of the first tasks will be to migrate it from Django 1.3 to something a little more recent! It’s kind of fun to go back to these old projects from time to time.
Refactor some code

Refactoring is a great way to ease back into a project for a number of reasons. You’re not building new behavior, so your goal is straightforward: you want to simplify the code, while maintaining consistent behavior. This can be easier than implementing a new feature.

I often sprinkle my exploratory code with # DEV comments, indicating places where I want to rethink the current implementation. Some people don’t like this, but I know many people who do something similar. When I get back to a stale project, reviewing these comments is a good way to start improving the codebase, usually without adding any new behavior.

Short code snippet, with a comment that starts with `# DEV`.
My `# DEV` notes show me where I want to rethink some very specific parts of the code. These are great places to pick up work. Here I know I want to run this on Windows and see if it works there.
Implement the smallest new feature you know of

Implementing new features can be really satisfying, because you can see your project evolve. Be really careful about this though, because if you don’t have any testing or documentation in place, building new features can backfire if you unintentionally change existing correct behavior.

Dogfooding

This isn’t distant advice about what I’d do if I were in this situation. I hop back and forth between different projects all the time, and often get pulled away from projects that I’m really excited to work on. Sometimes I’m pulled away for a few weeks, and sometimes it’s literally years before I can get back to a project I really want to finish.

I put a lot of work into django-simple-deploy last fall, and then had to put it aside to finish the online resources for the latest edition of Python Crash Course. I’m hoping to get back to work on django-simple-deploy in the next few weeks, and I’m going to do exactly what was described in this post. I’m planning to set up the project on a new computer, and then make sure I can run the current test suite successfully. I’ll document everything in an issue focused on resuming work, and then pick up with one of the most recent issues I was working on before I got pulled away.

Conclusions

Everyone who works on their own projects ends up with a number of dormant projects. These are excellent projects to consider going back to, often times with new motivation and a clarity of purpose. Much of what’s been discussed here also applies to jumping into an unfamiliar project in a professional setting.

No codebase is perfect, and no workflow is perfect. We all live in the real world, as do the projects we work on. When you find yourself going back to a project you’ve lost familiarity with, pick one of the steps described here and jump back in, knowing that you’re following a clear path back into a state of clarity and efficiency. When you’re actively working on a project, keep in mind that you could be pulled away from the project at any time, and give yourself some straightforward ways to get back into the project. Your future self will thank you.

Note: Do you have a dormant project that you’d like some help getting back into? I’d love to help someone apply some of what’s described here, and write a followup article about which specific ideas were most helpful. If you have a public project with a clear purpose that’s still in an exploratory phase, please feel free to reach out. In particular, if you’ve never written tests before and would like some help getting started with a test suite, I’d love to help. I can be reached at ehmatthes at gmail.


Resources

Simon Willison gave an excellent talk at DjangoCon US 2022 called Massively increase your productivity on personal projects with comprehensive documentation and automated tests. He describes his approach to managing projects in a way that lets him drop them at any time, and resume work at any point in the future without missing a beat. Simon is a prolific programmer, and his development practices are well-tested. You can see a writeup of his talk here, which includes a video of the actual talk.


  1. It’s really interesting to search all of GitHub for phrases like “resuming work” or “back up to speed”. You can find all kinds of examples of how people manage exactly what’s being discussed here. You can also see the wide variety of things that people use GitHub for. For example, I found someone who uses GitHub’s issue tracker on an otherwise empty repository to track their progress on the piano pieces they’re learning.

    (I only include screenshots from my own repositories and really popular repositories, because I don’t want to call attention to people who aren’t looking for it.)