I was talking with Kirk recently about AI and how it’s changing software engineering. During that conversation, I brought up John Henry. The more I think about it, the more I believe we’re having a John Henry moment in our industry.

If you’re not familiar with the story, John Henry was a steel-driving man who worked on the railroads. He was exceptionally good at his job, driving steel into rock with a hammer. When the railroad introduced a steam-powered drill, John Henry challenged it to a competition to prove that he could do the work better than a machine.

He won the competition but died from the effort.

The railroad kept using steam drills.

I don’t think AI is going to replace software engineers. At least not entirely, and certainly not anytime soon. However, I do think we need to reconsider how we define our value as engineers and what skills we should be developing.

Otherwise, we risk making the same mistake John Henry did.

Competing with the Machine#

For a long time, we’ve measured engineering productivity by how much work someone can produce. How many tickets did they complete? How much code did they write? How quickly can they implement a feature or fix a bug?

These measurements have never been particularly good indicators of engineering effectiveness, but they’ve been easy to track.

Now we have AI coding agents that can generate code, write tests, refactor existing implementations, and help debug problems in a fraction of the time it would take someone to do everything manually.

I’ve seen engineers respond to this by pointing out all the things AI gets wrong. The code isn’t as clean, it misses important context, or it makes architectural decisions that don’t make sense.

And they’re right. AI makes mistakes, sometimes pretty significant ones.

But I think we’re focusing on the wrong thing.

The question shouldn’t be whether we can write better code than AI. It should be whether writing code is the most valuable use of our time.

John Henry proved he could beat the steam drill. It didn’t change the fact that the railroad could accomplish more with machines.

I don’t want our industry spending the next several years trying to prove we’re better at something that’s becoming increasingly inexpensive to automate.

What Makes a Good Engineer?#

When I think about the best engineers I’ve worked with, their ability to write code quickly isn’t what stands out.

They’re good at understanding problems. They ask questions, challenge assumptions, recognize risks, and think through how their decisions will affect the rest of the system.

They understand the product and the people using it.

They know that a technically correct solution isn’t necessarily the right solution.

They can look at a feature request and recognize that what someone is asking for isn’t going to solve the problem they’re actually having.

They understand the tradeoffs between performance, maintainability, security, complexity, and delivery time. More importantly, they can explain those tradeoffs and help other people make informed decisions.

Sometimes the best engineering decision is to not build something at all.

None of this becomes less important because AI can write code. I would argue it becomes significantly more important.

If we can produce code faster than ever before, we can also produce bad code faster than ever before.

Think about how much effort it used to take to implement a poorly designed system. Something that required weeks of development might now be generated in an afternoon. That’s great if we’ve made good decisions about what we’re building. It’s a much bigger problem if we haven’t.

We’re reducing the cost of implementation, but we’re not necessarily reducing the cost of making bad decisions.

We should be spending more time understanding what needs to be built and why, rather than focusing entirely on how quickly we can build it.

Someone Still Needs to Know Where the Railroad Goes#

The steam drill was good at drilling holes. It didn’t know where to build the railroad, which route to take, or whether building a particular section made sense.

AI is obviously much more capable than a steam drill. It can help us reason through problems, evaluate different approaches, and even identify issues we might have missed.

But we still need engineers who understand the context and can take responsibility for the decisions being made.

We need people who understand our systems, our users, and our business. People who can identify what success looks like and determine whether what we’re building will actually get us there.

This is where I think the biggest change in software engineering is happening.

The value is shifting away from the mechanical work of producing code and toward understanding problems, designing solutions, and verifying results.

That doesn’t mean writing code isn’t important anymore. We still need to understand how software works, recognize when something is wrong, and be capable of investigating and fixing problems.

It means the act of writing code is becoming a smaller part of the overall engineering process.

And I think that’s a good thing.

What About Junior Engineers?#

There’s one part of this transition that concerns me, and I don’t think we have a good answer for it yet.

How do we develop experienced engineers when AI is doing much of the work that traditionally helped people gain experience?

Most senior engineers didn’t develop their judgment by reading about software engineering. They developed it by building things, making mistakes, debugging problems, and maintaining systems that weren’t always designed particularly well.

I’ve written plenty of bad code throughout my career. I’ve misunderstood requirements, made architectural decisions I later regretted, and spent more time than I’d like to admit figuring out why something wasn’t working.

Those experiences taught me things that I wouldn’t have learned otherwise.

Over time, you develop an intuition for recognizing problems before they happen. You start to understand why certain approaches tend to work and why others create problems down the road.

Now imagine starting your engineering career with an AI agent that handles most of the implementation work.

You might be able to deliver features much faster, but are you developing the skills needed to understand what you’re delivering?

I worry that we could end up with engineers who are excellent at getting AI to produce code but don’t have the experience needed to evaluate whether that code is any good.

As engineering leaders, we need to be thinking about this now.

We can’t just give junior engineers AI tools, celebrate the increase in productivity, and assume they’re developing the same skills that previous generations of engineers developed.

We need to be more deliberate about how we teach engineering judgment.

That means involving engineers in design decisions, making sure they understand the tradeoffs they’re making, and giving them opportunities to investigate problems rather than always accepting the first solution an AI produces.

I don’t think the answer is to keep junior engineers from using AI. That would be ridiculous. These tools are going to be part of how we build software, and engineers need to learn how to use them effectively.

But learning to use AI and learning to be a good engineer aren’t the same thing. We need to make sure we’re developing both.

Using AI Doesn’t Make You less of an Engineer#

I understand why some engineers are uncomfortable with AI. A lot of us have spent years developing our technical skills, and now we’re watching tools perform tasks that previously required considerable experience.

It’s understandable to be concerned about what that means for our careers.

But I don’t think refusing to use AI or constantly trying to prove we’re better than it is going to accomplish anything useful.

There will always be things that experienced engineers can do better than AI. There will also be things AI can do faster and, in some cases, better than we can.

I’m not particularly interested in competing with it.

I’m much more interested in what an experienced engineer can accomplish when they combine their knowledge and judgment with tools that dramatically reduce the amount of manual work required.

If AI can help us spend less time writing boilerplate, tracking down simple bugs, or implementing repetitive functionality, that’s time we can spend solving more important problems.

We should be looking for ways to use these tools to improve the outcomes we’re delivering, not just increase the amount of code we’re producing.

More code isn’t the goal. Delivering value is.

Of course, using AI doesn’t eliminate our responsibility for what we build. We still need to understand the solutions we’re delivering, verify that they work, and maintain them after they’re deployed.

If anything, being able to generate software so quickly makes that responsibility even more important.

Don’t Be John Henry#

John Henry was exceptionally good at his job. He worked hard, took pride in his abilities, and proved he could outperform a machine.

None of that mattered when the railroad decided how it wanted to get the work done.

I don’t want software engineers making the same mistake.

We shouldn’t be defining our value by how quickly we can write code or how much work we can do without assistance.

We should be focused on solving problems, making good decisions, building maintainable systems, and delivering value to the people using our software.

AI is changing how we accomplish those things, but it isn’t changing why we do them.

I think the engineers who will be most successful are the ones who embrace these tools while continuing to develop their technical knowledge, judgment, and understanding of the problems they’re solving.

And as engineering leaders, we need to make sure we’re helping people develop those skills rather than continuing to reward raw output.

John Henry knew how to swing a hammer better than anyone.

We need to make sure our engineers know where the railroad should go.