Write Code for the Engineer Who Comes After You

Write Code for the Engineer Who Comes After You

And that engineer is very often a future version of you

3 min read

There's a habit I try to instill in every engineer I work with, and it's less a technique than a posture. Work as though a future engineer is going to have to make sense of what you did today. More often than not, that future engineer is you, six months from now, with no memory of why any of this exists.

Future engineer equals future you#

This is the empathy heuristic at the heart of maintainable code. The "future engineer" isn't an abstraction; statistically it's frequently your own future self, staring at a function you wrote and wondering what on earth you were thinking. Once you internalize that, a lot of decisions get easier. You stop optimizing for the cleverness of the moment and start optimizing for the comprehension of someone who lacks all the context currently in your head.

Keep the onboarding docs alive#

Onboarding documentation and repository READMEs are the first thing a future engineer reads and the first thing teams let rot. I treat them as living artifacts with a clear maintenance trigger. Review and refresh them at three moments:

  • When someone joins the team and discovers what's outdated by stumbling over it.
  • When someone rolls off, taking context with them that the docs should now capture.
  • After every major release, when the system has meaningfully changed.

A README that lies is worse than no README, because it spends a newcomer's trust before they've written a line of code.

Treat code as living documentation#

The code itself is the documentation that's always there, so it had better be readable. A few practices carry most of the weight.

Refactor on every card. Whenever I touch an area to make a change, I take the opportunity to kill a smell or clarify something murky. Small, continuous improvement keeps the codebase from slowly degrading into something nobody wants to open.

Write self-documenting code. I lean on good names over comments wherever I can. A well-named function or variable explains itself and never falls out of sync with the code, the way a comment inevitably does. Comments earn their place explaining why, not what.

Name your tests as business rules. Automated tests are some of the best documentation you can write, but only if they read like statements of intent. A test named so that it describes the behavior in business terms tells the next engineer what the system is supposed to do, not merely that some assertion passed.

The question that gates "done"#

Before I'm willing to call a piece of work finished, I ask one question: would this be easy for a future engineer to understand? If the answer is no, then it isn't really done; it's just functionally complete and a liability waiting to surface. Passing tests and a working feature are necessary, but they aren't sufficient. Comprehensibility is part of the definition of done, not a nice-to-have you get to if there's time.

Why this compounds#

The payoff here isn't immediate, which is exactly why it gets skipped. The benefit lands weeks or months later, when someone picks up your work and moves quickly instead of slowly. A codebase written for future engineers stays cheap to change. One written for the convenience of the present moment accrues a tax that everyone, including your future self, pays with interest. Empathy for the next person turns out to be the most pragmatic engineering discipline I know.