When I was a junior developer, one of the most difficult skills I had to develop was reading code, or more specifically, understanding a large code base. Gone are the days of small personal projects, with four or five features and 20 files. Now apps are massive, with potentially hundreds of files all interacting in complex ways. Understanding a large code base can be daunting, so here are a few tips I have picked up from my time of onboarding onto various new projects.
Use the app.
This one may seem straightforward, but when I say, “Use the app,” I mean really dig into it. Try to get a good idea of what the designers were going for, why they implemented certain features, and how those might connect to other parts of the app. Follow a full workflow as if you were the end user trying to accomplish a specific task. Ideally, keep doing this until you have completed all tasks relevant to the job the app is capable of doing (though with some apps, this might be overkill). Take some time to use the app as if you were a quality assurance tester, following a full use of the application features from start to finish. Understanding what this app is actually trying to accomplish is a vital first step in understanding the underlying code.
Diagram important files and their functions.
A good diagram can be a massive learning and reference tool for keeping you mentally organized. As you learn, you can continue to add to it and refine it. Miro is a great tool for this. That’s because the diagram can have clean, easy-to-follow arrows showing how one file or function is referenced by another. It would be a good idea to share this with a team lead to check for accuracy. If something is wrong, it could provide valuable insight into how you’ve misunderstood the functionality, ultimately leading to a more accurate and thorough understanding of all the working parts.
Take one thing at a time!
When reading through the code, try to follow the functionality of one feature at a time. Start with a smaller function and trace it all the way down. What type of data does this function deal with? Does it need to make a call to an API to get this data? How does it modify or organize the data before displaying it to the user? Sometimes it may seem like an end-to-end process is simple, but along the way, several processes end up happening. This investigation may produce surprising results but will also help clear up why specific files handle certain processes.
Ask quality questions.
It’s important to ask good questions. Some examples of bad questions would be, “How does this app work?” or “What is this file doing?”
An example of good questions would be:
- “This file looks like it functions very similarly to this other file. What exactly are they doing differently?”
- “Most of the API calls are located here, but I can’t seem to find where the API calls for this specific set of data. Can you help me find where that happens?”
- “The data is modified in this very specific way here. Why is this data model favorable in this context?”
The more specific you can get the better. It shows the team that you’re taking time to understand the information yourself. Don’t forget to update your notes when you get an answer to a question that has you stumped.
Read the documentation, and if the documentation isn’t good, update it!
Documentation is there for a reason! If someone has taken the time to write good documentation, then reading it over will (usually) help you out. I say usually because sometimes it can be painfully out of date or simply non-existent. If this is the case, then you have a fantastic opportunity to test your knowledge of the app and gain huge brownie points with the team by updating the documentation yourself. Write up a draft and go over it with your team lead. Similar to reviewing your diagram, reviewing your idea of how things function can be a great way to catch any misunderstandings early.
Delete or modify things, and see how they change. Console log to get details.
A great way to figure out how something works is to break it! When deleting lines, you obviously need to be careful. Check out a separate branch, and only get rid of one thing at a time. Before checking out your local machine to see how the change affects how the code now functions, try to predict the changes that will happen. Will this break the entire app or will it only affect how a certain portion of the app is displayed?
Sometimes seemingly small pieces of code can have far-reaching consequences. This is a great time to fall back to that habit of following a piece of code thoroughly throughout a large code base, it may be farther reaching than you initially thought.
In addition to this, throwing in console logs wherever you need clarification is easy and can help clear any confucion up. Check some variables before and after functions to see how they change. Again, remember to first predict how you think it’s going to change by reading the code. Compare that to the actual result and check where you were right or wrong.
Be patient. Eventually things will start to click.
My final point is to be patient when trying to learn. Understanding a large code base is a long process and it won’t all make sense immediately. If you keep working at it, eventually everything will come into focus and your understanding of the app will come together.