DEV Community

Carlos Oliva Pascual
Carlos Oliva Pascual

Posted on • Originally published at stacknotice.com

How Senior Devs Use AI Without Losing Their Skills (2026)

There's a split happening in development teams right now.

On one side: developers who use AI tools and ship faster, debug quicker, and write better tests than they did a year ago. On the other: developers who use AI tools and can't explain the code they're committing, lose track of their own architecture, and struggle when the AI gives them something subtly wrong.

Same tools. Completely different outcomes.

The difference isn't the tool — it's the discipline around using it.


The Problem Nobody Talks About

Junior developers using AI as a search engine with autocomplete is fine. The problem is when the workflow becomes:

have a requirement → paste it into Claude → copy the output → commit
Enter fullscreen mode Exit fullscreen mode

This produces code that works — until it doesn't. And when it doesn't, the developer has no mental model of what the code is doing, no intuition for where to look, and no ability to debug it without going back to the AI.

That's not development. That's typing.

Senior developers use AI differently. They use it to move faster on things they already understand, not to bypass understanding.


The Framework: 3 Principles

Principle 1: AI executes, you architect

Decisions about structure, data flow, system design, and trade-offs are yours. The AI implements what you've already decided.

Right: "I've decided to use a repository pattern with a service layer. Generate the boilerplate for a UserRepository in TypeScript that follows this interface: [interface]"

Wrong: "How should I design my user management system?"

Principle 2: You must be able to explain every line you commit

If you can't explain it, you can't debug it, extend it, or review it in someone else's PR. When AI generates something you don't fully understand, that's a signal to stop and read it — not ship it.

Principle 3: Friction is deliberate practice

There's a category of tasks where doing it yourself, even if slower, makes you better. Senior developers know which friction to keep.


What to Always Delegate to AI

These are tasks where AI saves real time without costing you any skill:

Boilerplate and scaffolding

// Prompt: "Generate a Next.js API route for user profile updates.
// It should: validate with Zod, use Prisma, return typed errors,
// handle 401 if no session. Here's my User schema: [schema]"
Enter fullscreen mode Exit fullscreen mode

Test cases from existing code

// Prompt: "Write Jest tests for this function.
// Cover: happy path, empty array input, null values, async error."
// [paste the function]
Enter fullscreen mode Exit fullscreen mode

Regex and string transformations, JSDoc, migrations, repetitive refactors

You could write all of these yourself. You've done them before. Delegating them is resource allocation, not laziness.


What to Never Delegate

Debugging complex issues

When something is genuinely broken and you don't know why, your first move should NOT be to paste the error into Claude. The debugging process — reading the stack trace, forming a hypothesis, checking your assumptions, isolating the problem — is where you build the mental model of your system.

The right use of AI in debugging: After you've investigated and formed a hypothesis, AI is excellent at confirming your reasoning.

Wrong: "My component isn't updating. Here's the code, fix it."

Right: "I think the issue is that I'm mutating the signal's array
instead of replacing it with .update(). Here's the component.
Does this match what I'm seeing, and am I missing any other cases
where this pattern would cause the same bug?"
Enter fullscreen mode Exit fullscreen mode

Architecture and system design decisions

Use AI to explore options once you understand the trade-offs. Don't use it to decide.

Code review

The point of code review is to understand what a change does and whether it's correct. If you're using AI to review PRs without reading the diff yourself, you're missing the point.

Performance optimization judgment

Deciding which optimizations are worth the complexity cost requires understanding the actual usage patterns and the team's ability to maintain the change. That's engineering judgment — and it atrophies if you outsource it.


A Real Workflow: Building a Feature From Scratch

Here's how a senior developer actually builds a new feature with AI assistance.

Scenario: Add a notification system to a Next.js SaaS app.

Step 1: Design without AI (15-20 min)

Before opening any AI tool, answer these questions yourself:

- Where does the notification state live?
- What triggers notifications?
- Real-time or polling?
- How long do notifications persist?
- What's the read/unread state model?
Enter fullscreen mode Exit fullscreen mode

Write out the data model yourself:

interface Notification {
  id: string
  userId: string
  type: 'payment' | 'comment' | 'system'
  title: string
  body: string
  read: boolean
  createdAt: Date
  metadata?: Record<string, unknown>
}
Enter fullscreen mode Exit fullscreen mode

You made the decisions. Now you use AI to implement them.

Step 2: Generate the boilerplate

Prompt: "Generate a Drizzle ORM schema for this Notification interface.
Add indexes on userId and createdAt. Include a migration.
[paste the interface]"
Enter fullscreen mode Exit fullscreen mode

Review the output. Understand each method. Push back if something doesn't match your mental model.

Step 3: Write the component structure yourself

// Write the skeleton manually — you decide the props and state shape
export function NotificationBell({ userId }: { userId: string }) {
  // What state do I need here?
  // How does this connect to the server?
  // What's the loading state?
}
Enter fullscreen mode Exit fullscreen mode

Then fill in the implementation with AI assistance once the structure is clear.

Step 4: Generate tests from the implementation

Prompt: "Write Vitest tests for this NotificationService.
Mock the Drizzle client. Cover: returns only unread notifications,
markAsRead fails silently if notification belongs to different user."
Enter fullscreen mode Exit fullscreen mode

Run the tests. Read each one. Fix the ones that don't make sense.


Prompting Patterns That Make You Better

Ask for explanation before code

"Before writing the code, explain in 2-3 sentences what approach
you'll use and why. Then generate it."
Enter fullscreen mode Exit fullscreen mode

Ask for trade-offs

"Give me two implementations: one optimized for readability,
one for performance. Explain the trade-off."
Enter fullscreen mode Exit fullscreen mode

Challenge the output

"What are the failure modes of this implementation?
What would break it in production that a unit test wouldn't catch?"
Enter fullscreen mode Exit fullscreen mode

Ask it to teach

"Why does TypeScript infer this type as 'never' here?
Explain the mechanism, not just the fix."
Enter fullscreen mode Exit fullscreen mode

Staying Sharp: Deliberate Practice

  • Keep one weekly challenge without AI — Advent of Code, Exercism, or a self-imposed constraint on a side project
  • Read the generated code actively — what did the AI do differently? What pattern can you internalize?
  • Own the debugging — 30 minutes of your own investigation before going to AI
  • Review AI-generated PRs as if you wrote them — can you explain each function?

The Red Flags

  • You can't reproduce the bug that the AI "fixed"
  • You're asking "how should I build this?" before thinking about it yourself
  • You feel anxious when the AI is unavailable
  • You're copying AI output without reading it because "it usually works"
  • The architecture of your project has drifted and you're not sure how

The Actual Advantage

The developers getting the most from AI tools aren't the ones who use it most — they're the ones who use it most precisely.

The skill is still what matters. AI just changes where you spend it.


Full article with the complete feature walkthrough and more prompting patterns at stacknotice.com

Top comments (0)