Working on Inherited Code Bases

Sameera Gayan
March 21, 2019

If you are a freelance developer or working for a project / consultancy company like us here at reinteractive, there is a good chance you’ll be working on inherited codebases that were created by other developers/agencies. Unlike greenfield projects, existing codebases come with uncertainty and a lack of background knowledge that you normally get from a project created by you or your own company.

To make this situation even more challenging, these projects usually come with tight deadlines so there is limited time for you to fully understand the codebase.

Following are few tips that you may find helpful when working with such projects.

Get The Project Up and Running

Understand the Project

It is important for you to have an idea of what the project is about, and it’s functionality. Get your client to provide a walkthrough of the project and show you around. Make sure you understand the critical component(s) of the system. These are the features that the business needs in order to function and may or may not be the ones that are the most technically complex. You should take extra care when working around these components.


Have a look at the README file. Ideally it should have the details on setting up the project. Try following it and see how far you can go. If you find deviations, update the README so that by the end of project setup, you will have an up to date README. At reinteractive, we follow this default README as the base for our projects and build on it from there as required.

External Dependencies / Keys

Almost all projects nowadays have at least one external dependency, such as sending emails via a third-party SMTP. Make sure you have all the access keys, urls, passwords, etc to access those services. A good example would be, Stripe. If the project is using Stripe, make sure you have all the keys and you as a developer can login to the Stripe dashboard. (Ideally as a developer role)

If the project documentation doesn’t provide enough information to access these services, typical places to look for (in a Rails app) would be:

  • Gem file
  • config/initializers
  • .env file (if the project has one)
  • config/environments

Get All the Details In One Place

Once you have all the details you need, put them in one place so you can access them quickly. This includes access keys, logins etc and even the small things like deployment commands. I typically use 1Password for keys and Evernote to keep the non-sensitive information. I have a ‘notebook’ for each project and notes for each section of the project.

Technical Rundown

This point may be subjective and most of the time we don’t get this luxury. But, if possible, arrange a time with the previous developer(s) for a technical walkthrough. Before this walkthrough, I’d highly recommend going through the codebase and having your questions / clarifications ready.

Understand the Current State of the Project

Now you are all set up and ready to begin work, it is important that you and the client understand the current state of the project.

Your development times are affected by a number of factors in the code; mainly the quality and also the test suite. Your client may not instinctively understand this because these issues are not client facing.

Having this understanding between you and the client will help you explain why some changes that appear simple may be somewhat complex and time-consuming to implement.

Typical methods you can use are:

  • check the test coverage. simplecov
  • check the security issues that the code may have using brakeman
  • check the code quality rubocop important: this does not mean that you need to fix them before working on client issues, it is purely to further understand the code we are working with.

Make Sure You Can Deploy

One of the frequently overlooked things when it comes to inheriting an exiting codebase is the deploy process. Deploying changes (initially to staging at least) is the primary way your client can view your progress and how they will test your code. Don’t wait until the last minute to see if you can deploy the project (to staging / production).

After you complete the above steps, do a deploy and make sure it works. You don’t have to work on an actual fix. Change something in the README, deploy, and see if it works. It’s very common that the deploy workflow in the README is not working as expected in a real deploy.

Client Communication

Regular and frequent communication with the client is very important for any project. It is particularly critical if you are working with a project that you are not familiar with. If you are working on a tight deadline, arrange someone from the clients end who can respond promptly to your queries. That will save you a lot of time, from trying to figure out how a feature is working or even how to get to a certain page to test something.

Create a List of Critical Issues and Focus on That

This is especially critical for the codebase you inherited that has a tight deadline: make sure you go through the issue list with the client and pick the ones that are most critical to the upcoming release. If the client finds more issues or comes up with additional features, add them as seperate tickets and filter them again based on their criticality.

It’s easy to get sidetracked from your main issue list when the UAT is happening and client requests new changes. But the important thing is to keep your focus on the release issue list.

Improve the Code as You Work on It

Typically, we cannot set aside time purely for improving code. We have to do it as and when we work on it. Depending on the time available, I’d suggest improving the code whenever you see an opportunity for improvement. It doesn’t have to be a full overhaul, as small changes in the right direction add up over time.

As an example, I was working on a controller that had many functions inside a standard REST method (UPDATE). Functionality like this should ideally be moved to a service object for better code maintenance and easier testing. However, this code was coupled with some controller bind functionality and couldn’t easily be moved to a service. As a first step, I moved the functionality to a private method within the controller. This way, the next time a developer works on this code, he/she only has to focus on refactoring the private method.

Deploy/get UAT Often

Feedback loops play a major role when you are working on time-pressed project. It’s important to get feedback from the client as soon as possible to re-affirm that the project is moving in the right direction.

Don’t wait until the end of the day to push all your fixes, push them often and get the client to test them often.

I hope you find these tips useful, and let me know if you have any more too. Happy coding!