I write less code than ever. And yet I’m more productive than I’ve been in years. That feels paradoxical, but it’s true: my role has shifted. I type less, but I think more. The question is no longer “how do I implement this?” but “what should be built here, and why?”

That’s not a small shift. For most of us, our identity as a developer is closely tied to writing code. The craft of getting a complex algorithm right, the satisfaction of a clean refactor, the flow state when everything clicks. And now a tool comes along that does that part for you — often faster and sometimes better.

The real question is: what’s left? And the answer, I think, is more interesting than you’d expect.


The old workflow vs. the new

A year ago, building a new endpoint in our ASP.NET Core API looked like this: I’d look at an existing endpoint, copy the structure, write the controller or minimal API handler, add the validation, register the DI dependencies, write the tests. Most of the time I knew exactly what needed to happen. The work was in the typing.

Now that same feature starts differently. I describe what the endpoint should do, what the request and response look like, and how it fits with the existing patterns. Claude Code reads the codebase, sees that we use Minimal APIs with a specific folder structure, and generates the endpoint including validation, error handling, and tests. My job is to review whether it fits.

That sounds faster. And it is — for the implementation part. But here’s what I didn’t expect: the thinking part takes longer now. Not because AI makes it harder, but because I can no longer hide behind the typing. When writing code yourself, you can start with a vague idea and let it crystallize as you type. With AI, you need to be precise about what you want before anything gets generated.

That precision is the new skill.


What you can delegate — and what you can’t

After months of daily work with Claude Code, I have a pretty clear picture of what I can hand off and what I can’t. The line isn’t where I expected it.

What works well to delegate:

  • Boilerplate: CRUD endpoints, DTOs, mapping code, DI registration
  • Tests: unit tests following an existing pattern, especially when you point to an example test file
  • Refactoring: extracting a class, renaming consistently, splitting a large method
  • Standard patterns: repository implementations, event handlers, middleware — anything where the pattern is clear

What doesn’t work to delegate:

  • “Should this be a separate service or part of the existing one?” — architectural decisions that depend on your domain
  • “Is eventual consistency acceptable here, or do we need a transaction?” — trade-offs that require understanding the business context
  • “Does this fit with how our team works?” — team conventions that aren’t captured anywhere

Here’s a concrete example. I asked Claude to add caching to a service. It generated a perfectly implemented IMemoryCache integration. Clean code, correct usage, even with proper cache invalidation. But we use Redis in production because our API runs on multiple instances. IMemoryCache was the wrong choice — not because it doesn’t work, but because it doesn’t fit our infrastructure.

Claude couldn’t know that. And that’s the point: the implementation was technically correct, but architecturally wrong. Catching that is your job. Not the typing — the thinking.


The skills that matter now

Three skills have become more important in my daily work. None of them are about writing code.

Systems thinking

When Claude generates code, it solves the local problem. Add an endpoint? Done. Write a test? Done. But software isn’t a collection of isolated parts. It’s a system where everything connects: the DI container wires services together, middleware handles cross-cutting concerns, events flow through handlers.

Your job is to keep the overview. Does this new service need to be scoped or singleton? Does this event handler need to be idempotent because the message broker might retry? Does this endpoint need rate limiting because it’s public-facing?

These aren’t implementation questions. They’re architecture questions. And they require understanding the whole system, not just the file you’re looking at.

Code review as a core skill

Code review was always important. But it used to be something you did for colleagues. Now it’s something you do for every piece of generated code — and you do it dozens of times a day.

That changes the skill. You’re not just looking for bugs. You’re asking: does this fit? Does it follow our naming conventions? Does the error handling match what we do elsewhere? Is the abstraction level right, or is it over-engineered?

I’ve noticed that my reviews have become sharper since I started working with AI. Because I’m reviewing more code, I’ve developed a better eye for inconsistencies. That’s an unexpected benefit.

Specifying clearly

This is the big one. The quality of your output depends entirely on how well you can describe what you want. Not in code — in words.

That means: being precise about behavior, not implementation. Describing constraints explicitly. Pointing to existing patterns instead of hoping Claude finds them. Knowing what “done” looks like before you start.

This is, in a sense, the new form of coding. Instead of writing if (order.Status == OrderStatus.Cancelled), you write: “When an order is cancelled, send a notification using our existing IEventHandler pattern. Look at how we handle OrderShipped for the structure.”

The precision is the same. The medium is different.


The uncomfortable truth

Not everyone finds this comfortable. And I think that’s worth saying.

If your identity as a developer is built on “I write clean, elegant code”, it feels strange to hand that over. There’s a real sense of loss when you realize that the craft you spent years perfecting can now be automated.

But I’ve come to believe that the value was never in the typing. It was in the understanding. Knowing why a certain pattern is the right choice. Knowing when an abstraction helps and when it hurts. Knowing what questions to ask before a single line of code is written.

That understanding doesn’t become less important with AI. It becomes more important. Because now you’re not just responsible for the code you write. You’re responsible for the code you accept. And accepting bad code because it was generated quickly is worse than writing it slowly yourself.

The developers I see struggling most with AI are those who skip the review. Not because they’re lazy, but because the code looks right. It compiles, the tests pass, the structure seems familiar. But “looks right” and “is right” are different things — especially when it comes to how code fits into a larger system.


Your title doesn’t change. Your work does.

I still call myself a developer. I still build software every day. But what that means has shifted. Less time in the editor, more time thinking about design. Less typing, more reviewing. Less “how”, more “what” and “why”.

The best developers in the coming years won’t be the fastest typists. They’ll be the sharpest thinkers. The ones who can look at generated code and see not just whether it works, but whether it belongs.

Next time you start a feature, try this: before you type a single prompt, write down — in plain language — what you want to build, why, and how it should fit with what’s already there. Describe it as if you’re briefing a skilled colleague who doesn’t know your codebase. That exercise is the work now. The implementation follows.