ع
Start Topics Teams Reference What's new Saved
Workflows & power-user

Where does this come from, where is it used?

Every trace runs one of two ways — backward toward where something came from, or forward toward what depends on it. The second one is the question people skip, and it's the one that decides whether a change is safe.

9 min read · Updated 2026-08-16
Where does this come from, where is it used?

Code is a web. Almost nothing in a codebase stands alone: a function calls another function, a value is set in one place and read in three others, a number typed into a form travels through half a dozen files before it lands in a database and comes back out on a screen. Understanding any single piece means understanding what it’s attached to.

Which gives you exactly two questions, and they’re the same question pointed in opposite directions.

Where did this come from? — backward, toward the source. Where is this used? — forward, toward the consequences.

Both of these used to be genuinely expensive. You’d open the project in an editor, run text searches, follow imports by hand, keep four files open at once and a mental stack of this is called from here, which is called from here, which I think is called from…. In an unfamiliar codebase an hour could vanish into a single trace, which meant people rationed their curiosity. They traced when they had to, and guessed the rest of the time.

That cost is now a sentence in the chat. It’s worth sitting with how large a change that is, because the right response isn’t to trace slightly more often. It’s to trace constantly — including when you don’t strictly need to — because the thing that made it a specialist skill was never the difficulty. It was the price.

Backward: where did this come from?

Say you’re looking at a function called saveMessage, and it’s handed an object called msg. Where did that come from? You don’t need to scroll, and you don’t need to know the project. You ask:

where does the msg that saveMessage receives come from? Trace it back.

What comes back isn’t a location, it’s a chain — “it’s built in handleContact in server/index.js out of req.body: the name, email and message someone typed into contact.html, then passed straight into saveMessage.”

That sentence is a real model of how the system is wired, and notice that you could not have obtained it by reading. It isn’t written down anywhere. It exists only as a path across four files, and something had to walk the path to describe it.

Forward: what depends on this?

Now flip the direction, because this is the one people skip.

You’ve understood what a function does. The next question is who relies on it — and that’s the question that tells you whether changing it is safe.

what calls sendNotification? List every file and what it does with the result.

An answer like “one caller — handleContact in server/index.js, which calls it right after saving and ignores what it returns” is worth more than it looks. In one line you now know what breaks if you get this wrong, whether your replacement has to hand back the same kind of value, and that email is sent from exactly one place — so changing how email works is a one-file job rather than an expedition.

This is the question experienced developers ask before every meaningful change, and it’s the difference between “I’ll just move this function” and “why is production down?” It is also, not coincidentally, a blast radius question: you’re establishing how far the consequences of an edit can travel before you make it.

The same move, four shapes

Once you have the shape, the variations are obvious. All of them are start at one point, follow the wire:

Trace data backwardwhere do the messages in messages.json actually come from? Trace it back to the form.

Trace data forwardwhen someone submits the contact form, what happens? Walk me through every function that runs, in order.

Trace the importswhat does server/index.js pull in, and what does each one do?

Find where something liveswhere in this project does the email actually get sent?

That last one deserves a note, because it’s the one that rescues people. You often don’t have a symbol to start from — you have a behaviour. Something shows the wrong date, an email goes out with the wrong name, a total is off by a cent. You can trace from a description just as well as from a name, and for anyone who doesn’t write code for a living, that’s usually where the trace actually begins.

Ask for the list, not the answer

Here’s the one habit worth taking from this page.

You will be tempted to ask “is this function used anywhere?” and act on the yes. Don’t. Always ask for the callers to be listed, file by file, for two reasons that compound.

The first is that a yes tells you almost nothing. You didn’t want to know whether it’s used, you wanted to know what would happen if you changed it, and only the list answers that.

The second is the important one: a list is checkable, and a yes isn’t. If you’re given five files, you can open one and confirm it really does call the thing. That takes fifteen seconds and it is the entire difference between a trace you can rely on and a trace that merely sounds right. Claude reads real files and is usually right — but “usually right” is a property you want to be able to test cheaply, and a list is what makes the test cheap. A yes gives you nothing to pull on.

A trace you can’t verify isn’t a trace. It’s a story.

That’s also why asking for a list quietly improves the answer itself rather than just your ability to audit it. A request to enumerate every caller is a harder question than a request to confirm a hunch, and it produces a more careful reading. You get a better trace and a checkable one from the same sentence.

Where this pays off

Tracing is the move that turns an unfamiliar codebase from a wall into a map, and it compounds in a way that’s easy to underrate: every trace you run leaves you knowing a little more about how the system is shaped, so the next one starts from higher ground.

It’s also the right first move in the situation that sends most people looking for help in the first place — inheriting something nobody left documentation for. You don’t need anyone to remember how it works. You need a point you recognise and a direction to walk in.

The other half of reading code is what to do when it’s broken rather than merely unfamiliar: the wall of red text, the stack trace, the error that names a file you’ve never heard of. That’s reading errors, and it’s the same instinct pointed at a different problem.

Topics

Questions people ask

I'm about to rename something. What should I ask first?
Ask for the callers, by file: *"list every file that calls formatPrice, and show me how each one uses it."* A rename is safe exactly when you know everywhere the old name appears, and a file-by-file list is something you can spot-check in seconds. The tempting questions — *is this a good name?*, *should I rename it?* — are fine, but they don't tell you what breaks. This one does.
Why not just ask whether a function is used anywhere?
Because *"yes, it's used"* is not actionable and not checkable. You can't open a yes. Ask for the list of callers and you get two things at once: the information you actually needed, and a claim you can verify by opening one of the named files. A yes/no answer hides both the detail and the mistake.
Can I trust a trace without checking it?
Treat it the way you'd treat a colleague's verbal summary — probably right, worth confirming before you act on it. The cheap check is to open one link in the chain and confirm it says what the trace claims. If the trace named five callers, look at one. That single spot-check is usually enough to tell a real trace from a plausible-sounding one, and it takes about fifteen seconds.
Does this work on a codebase nobody at the company understands anymore?
That's the case it's best at. Tracing doesn't require anyone to remember how the system works — it reads what's actually there, which is precisely the thing the institutional memory has lost. Start at any point you *do* recognise (a screen, a button, an error message, a filename) and trace outward from it. The map assembles itself from wherever you happen to start.
Put it into practice
Browse the topics
Start