← ALL POSTS
CAREER APR 29, 2026·8 MIN

What mentoring junior devs taught me about my own code

Code reviews are a two-way street — here's what teaching sharpened in my own habits.

rj
Rollie John Jaictin
Senior Software Developer
Developers gathered around a desk reviewing code together

Explaining a decision out loud is a good test of whether the decision was actually sound. Mentoring made that obvious pretty quickly.

Key Takeaways

  • Explaining code patterns to someone new forces you to justify the choice — and often reveals simpler alternatives
  • Code review conversations about tradeoffs are more valuable than catching bugs
  • Teaching junior devs sharpens your own pull request habits before anyone else sees your work
  • The best mentoring is bidirectional: you learn as much as you teach

If you can’t explain it simply, it shouldn’t be there

A few times I caught myself reaching for a pattern out of habit rather than need. Having to justify it to someone new was usually the moment I realized a simpler approach would do.

Example: I had written an elaborate factory pattern for creating API client instances. The code worked, but when a junior asked “why not just export a function?”, I couldn’t defend the factory. The simpler version:

// Before: factory pattern (over-engineered)
class ClientFactory {
  constructor(config) {
    this.config = config;
  }

  create(endpoint) {
    return new ApiClient(this.config, endpoint);
  }
}

const factory = new ClientFactory({ baseURL: 'https://api.example.com' });
const userClient = factory.create('/users');

// After: just a function
export const createClient = (endpoint, baseURL = 'https://api.example.com') => {
  return new ApiClient(baseURL, endpoint);
};

const userClient = createClient('/users');

Second version is clearer, testable, and five lines shorter. I’d reached for the factory because I’d used it before, not because it solved a real problem.

That pattern repeats: you default to what you’ve done before, then a question from a junior forces you to reexamine it.

Reviews go both ways

The best reviews I’ve given weren’t about catching bugs — they were conversations about tradeoffs. Talking through the “why” behind a design choice often uncovers issues I wouldn’t have spotted with a diff alone.

When a junior proposes a solution, ask:

  • “Why did you choose this over [alternative]?"
  • "What breaks if we change [assumption]?"
  • "How does this scale to 10x the data?”

Their answer either clarifies the choice or reveals an oversight. Either way, the conversation shapes their thinking — and yours.

Those same conversations, when I’m the one proposing the code, have sharpened how I evaluate my own work:

// Code I submitted for review (and would have missed the issue)
const processUsers = async (users) => {
  const results = [];
  for (const user of users) {
    const result = await fetchUserDetails(user.id);
    results.push(result);
  }
  return results;
};

// Reviewer (junior): "Why fetch one at a time? Can you batch these?"
// Me: I didn't have a reason. Changed to:

const processUsers = async (users) => {
  const ids = users.map(u => u.id);
  return Promise.all(ids.map(id => fetchUserDetails(id)));
};

// Actually better: if the API supports bulk fetch
const processUsers = async (users) => {
  return fetchUserDetailsBatch(users.map(u => u.id));
};

The junior didn’t catch a bug, but they caught inefficiency. Now I ask that question about my own code before submitting.

Feedback is feedback

When you’re mentoring, you get a lot of “why” questions. Some feel obvious to you; others expose your own blind spots. That friction is valuable.

A junior asked why I was checking for null in one place but not in another:

// My code
if (user !== null) {
  processUser(user);
}

// Later in the same function
const name = user.name; // What if user is null here?

I had gotten lazy. I checked once, then assumed it held. Teaching them to be consistent forced me to apply the same rigor.

Teaching sharpens your own pull requests

After mentoring for a few months, my own pull requests got tighter:

  • Better commit messages (I was explaining changes to someone else, so I got precise)
  • Smaller diffs (I learned to break work into reviewable chunks by reviewing others’ work)
  • Clearer variable names (I couldn’t assume shared context the way I would with peers)
  • Comments only where the why is non-obvious (I stopped over-documenting)

The skills transfer directly.

Concrete before abstract

One pattern I’ve learned to use in reviews: ask for a concrete example before accepting an abstract rule.

Junior: “We should always use dependency injection.” Me: “Show me the refactor on this code. What’s the concrete benefit?”

Often, they’ll find the principle doesn’t apply to the specific code. Other times, the refactor is clearly better and suddenly they understand why the rule exists.

That approach — moving from abstract to concrete — has become my default in mentoring and in reviewing my own code.

Takeaways

Teaching junior devs isn’t a one-way transfer of knowledge. It’s one of the better habits you can build for your own code review process, even when you’re the one supposedly doing the teaching. Explain decisions out loud, treat tradeoff conversations as the real value of code review, and let questions from others sharpen how you evaluate your own work before anyone else sees it. The rigor you bring to mentoring tightens your own practice.