Reading code to onboard onto a new codebase sounds simple until you’re actually doing it. You start tracing a single user flow, follow a maze of dependency injections, and before you know it, you’ve opened more tabs than lines of code you'll actually end up writing, completely disconnected from the ticket on your board.
In my five years as a software engineer, most recently on the Paid Ads team at Wix, I’ve had to do this quite a few times. My default approach was always the same: long code deep dives until I felt I had grasped the basic functionality as much as possible. It worked, but it always felt passive. I was reading without direction, exploring without a clear goal, and taking far longer than I needed to.
So when I joined Wix, I decided to build a method for myself. One that would make onboarding faster, more structured, and actually fun. I started treating the codebase like an open-world game.
Why Codebases Feel Hard to Learn
Before getting to the method, it's worth being honest about why onboarding onto a new codebase is genuinely difficult, and not just for junior engineers.
Modern systems are distributed and complex. A single user action can touch five services, two queues, a cache layer, and a database, none of which are obvious from reading any one file.
Knowledge Is Fragmented: The reason a piece of code was written a certain way often isn't in the code itself. It's in a PR description from months ago, an archived Slack thread, or a post-mortem doc that someone created and never shared to a common folder. The code is the output of decisions; the decisions themselves live elsewhere. No matter how hard we try to keep everything in one place, reality rarely works out that way.
Every Codebase Has Different Rules: Not all patterns you learned at your last job apply here. In fact, sometimes most of them don't. By definition, you are a beginner every time you touch new code because every codebase is different. How services are structured, how errors are handled, which clean code conventions are followed: it’s all contextual.
The Open-World Mindset
In open-world games, you're dropped into an exciting new world and can explore it freely. The fun of it is that there's no specific path you're forced to follow. You can wander, pursue what interests you, and discover the map over time.
Codebases work the same way, or at least they can. You don't have to start at the top of the file tree and work your way down. You can start where the system is most relevant to you, follow a thread, and let understanding accumulate naturally.
The key shift is from passive reading to active exploration. Stop trying to memorize the codebase and focus on building a mental map.
That map gets richer the more you move around, and the best part is that it takes off the pressure to understand everything at once. Once you trace and understand a complete end-to-end flow, you already have enough context to contribute. You don't need to know the entire codebase to start shipping code.
Your Map Is Bigger Than the Code
Here's something that took me a while to internalize: the code is just one part of the full picture.
As software engineers, we are used to thinking of understanding a system as reading its source files. But today, the context that makes a codebase legible is distributed across many places: GitHub PRs and commit history, Slack conversations, Grafana dashboards, logs, documentation, and incident reports. Each of these tells you something the code itself doesn't.
GitHub PRs: A PR from eight months ago explains why a particular abstraction exists.
Grafana Dashboards: Shows you how the system actually behaves at runtime, not just how it's supposed to behave.
Production Logs: Shows you the paths users actually take, not just the paths the code makes possible.
With MCP integrations and your favorite AI coding tool (or several), you can now query across all of these sources at once in just a few seconds, asking questions like "What changed in this service around the time this metric started spiking?" and getting answers that just two years ago would have taken hours to piece together manually. The map of a modern system isn't just the repository anymore, and leveraging all of that context makes exploration much faster and easier.
AI Is Your Sidekick
In many video games (and TV shows), the main character has a sidekick. Most of the time, that sidekick has abilities you as the main character don't have. It’s not because they are more important, but you have to use their skills to succeed in your missions.
AI tools in the context of codebase onboarding work the exact same way: you should use them, but you are still the one in charge, the owner of the code you ship.
Here are a few ways your sidekick can help you navigate the map:
Explaining unfamiliar areas: Asking "What is the main responsibility of this microservice, and how does data flow through it end-to-end?" gives you a structural baseline immediately and saves you from manually tracing handler calls through the repo just to figure out where execution starts.
Highlighting risks: Asking "Use GitHub search to figure out if changing the data format in this file will affect other consumers in our org" surfaces cross-repo dependencies right away, showing you who relies on your code before you go searching in hopes you won't miss an edge case.
Connecting code to context: With MCP tools tied into your workspace, you can ask "Has this service been mentioned in recent post-mortems, incident reports, or Slack discussions about performance issues?" It lets you search the code and its production history simultaneously.
Guiding you through the map: Asking "I have my first ticket for this repo. What are the core flows I should focus on?" gives you a targeted starting point instead of just reading through piles of unfamiliar (and at times unwelcoming) code.
Using AI during onboarding is not at all cheating. Done right, it won't make your understanding shallow: it will give you a quicker way in and help you succeed in your missions.
Boss Fights Require Preparation
In open-world games, you can wander freely most of the time, but boss fights are different. They're the moments where you face something genuinely difficult and cannot afford to be underprepared.
In a new codebase, boss fights are the moments when you first have to touch something complex, high-stakes, and unfamiliar. An authentication flow. A payment handler. A piece of legacy infrastructure that hasn't been touched in a very long time (bonus points if it's written in a language you don’t know). We've all seen those.
The instinct is to just dive in, read the code, figure it out, make the change. Sometimes that works, but other times it doesn't, and you find yourself mid-PR with more questions than when you started.
For boss fights, deliberate preparation makes all the difference. A useful sequence in my experience would be:
Gather context first: Before touching any code, understand what this feature actually does and why it exists. Read the PRs that introduced it.
Talk to the owners: Someone always knows more than the code says. Find them. Five minutes of conversation can save hours of reading.
Understand the history: How has this part of the system changed over time? What broke before? History tells you where the danger lies.
Test safely: Before making any change to something you don't fully understand, make sure you know how to verify that nothing broke. Feature flags, staging environments, rollback plans: figure these out before you need them.
To prepare for any given boss fight, use your common sense and ask yourself one question: "What would make it 10 times less likely for me to mess this up?"
Knowing what you need to do to prepare makes it much more likely that you'll actually do it.
The Playbook
A few habits that make the open-world mindset stick in practice:
Follow what interests you: Start with the part of the system that's most relevant to your first task, or the part you're most curious about. Curiosity is a better guide through a codebase than any prescribed reading order.
Build the map actively: Keep notes on what you're learning. Draw diagrams if it helps, or explain your understanding to a teammate. The act of externalizing your mental model reveals gaps faster than reading alone.
Don't try to understand everything at once: Open-world games don't expect you to explore the entire map in the first hour. Build understanding gradually; the whole picture reveals itself as the gameplay hours pile on.
Use your sidekick: The AI tools are there. The MCP integrations are there. Using them is just playing well with the tools available.
Respect the boss fights: When you're about to touch something complex and high-stakes, slow down and prepare deliberately. The cost of getting it wrong in an unfamiliar codebase is higher than in familiar territory.
A codebase is a map, but the repository is only one territory.
You don't need to memorize every file before you can make a meaningful impact. Trace an end-to-end flow, use your tools to uncover the history, and build your mental map as you go.
Like any good open-world game, a new codebase gets so much more interesting the more you explore it. Next time you face a new codebase, just start exploring!
You can also watch this great Wix Engineering Conference 2026 session by Shahar - "Leveling Up in a New Codebase":
This post was written by Shahar Mayzel
More of Wix Engineering's updates and insights:
Join our Telegram
Visit us on GitHub
Subscribe to our YouTube channel