Skip to main content
Ganesh Joshi
Back to Blogs

Pair programming with AI

February 13, 20265 min read
AI & coding
Programming code on screen

Treating the AI as a pair partner works best when you decide what it should do at each step: explain, suggest, or implement. That keeps you in the driver's seat and makes the output easier to trust and maintain.

What is pair programming with AI?

Traditional pair programming involves two developers: one writes code (the "driver") while the other reviews and guides (the "navigator"). With AI, you are always the driver, and the AI is a capable but fallible navigator that can:

  • Explain unfamiliar code or patterns
  • Suggest implementations or approaches
  • Generate code based on your specifications
  • Review your code and suggest improvements
  • Help debug issues by analyzing errors

The key difference: AI does not have context about your project's goals, constraints, or history. You provide that context and make the decisions.

When to ask for explanation

Use explanation mode when you need to understand something before changing it:

Good times to ask for explanation:

  • Reading unfamiliar code: "Explain what this function does step by step"
  • Understanding algorithms: "What is the time complexity of this? How does it work?"
  • Learning patterns: "How does this React hook pattern work?"
  • Debugging: "Why might this code throw a null reference error?"

Explanations help you build mental models. Use them before asking for changes so you know what you are modifying.

Example conversation

You: Explain what this useEffect does and why it has these dependencies.

AI: This useEffect runs whenever `userId` changes. It fetches user data 
    from the API and stores it in state. The dependency array [userId] 
    ensures the effect only re-runs when the user ID changes, not on 
    every render. The cleanup function cancels the fetch if the component 
    unmounts or userId changes before the fetch completes.

You: Got it. Now I can safely modify the loading state handling.

When to ask for implementation

Use implementation mode when the task is well-defined and you know what you want:

Good times to ask for implementation:

  • Clear, bounded tasks: "Add error handling to this function"
  • Syntax conversions: "Convert this to async/await"
  • Boilerplate: "Create a test file for this component"
  • Repetitive code: "Add similar validation for these other fields"

Give the AI the file, relevant snippet, and exact change you want. After you get a suggestion, read it and run it; do not accept blindly.

Example conversation

You: Add try/catch error handling to this async function. 
     Log errors to console and return null on failure.

AI: [provides updated function with try/catch]

You: [reviews code, runs tests]
     This looks good, but use our logger instead of console.error.

AI: [provides updated version using your logger]

Keep architecture and design decisions yours

AI can suggest implementations, but you choose:

  • Module structure: Which folders and files exist
  • Data flow: How information moves through the system
  • Dependencies: Which libraries to use
  • Patterns: Component structure, state management, API design
  • Naming: Conventions that fit your codebase

If AI proposes a big refactor or a new dependency, treat it as a proposal. Ask yourself:

  • Does this fit our architecture?
  • Is this dependency worth adding?
  • Will this be maintainable?
  • Does this match our team's conventions?

You decide. AI helps execute your decisions.

How to iterate in small steps

Large requests lead to large, hard-to-review outputs. Break work into small steps:

Instead of Try
"Rewrite this whole module" "Extract this validation into a separate function"
"Add comprehensive test coverage" "Add a test for the empty input case"
"Refactor this to be cleaner" "Split this function into two: one for fetch, one for transform"
"Fix all the TypeScript errors" "Fix the type error on line 42"

Small steps are easier to:

  • Verify: You can review a 10-line change quickly
  • Roll back: If something breaks, you know which change caused it
  • Correct: You can fix issues before they compound

Chain several small requests, but ensure each step is something you can review in one go.

How to correct the AI

When output does not match your intent, say so clearly:

  • Be specific: "This doesn't handle null" not "this is wrong"
  • Reference the code: "Line 12 should use optional chaining"
  • State the fix: "Use our logger, not console.error"
  • Provide context: "We never throw errors in this layer; return a Result type instead"

Correcting early avoids a long chain of wrong assumptions. The AI adjusts based on your feedback.

Example corrections

You: This implementation logs to console, but we use a custom logger. 
     Replace console.error with logger.error from @/lib/logger.

You: This function doesn't handle the case where data is undefined. 
     Add an early return for that case.

You: The naming doesn't match our conventions. Rename `getData` to 
     `fetchUserProfile` to match the other fetchers in this file.

Common mistakes to avoid

Mistake Why it is a problem Better approach
Accepting code without reading Bugs and style issues slip through Review every line before committing
Asking for huge changes Hard to review, hard to roll back Break into small, focused requests
Letting AI decide architecture AI lacks project context Keep design decisions yours
Not providing context AI makes wrong assumptions Paste relevant code, types, constraints
Ignoring AI suggestions May miss good ideas Evaluate suggestions, then decide

Practical workflow

Here is a workflow for effective AI pair programming:

  1. Understand first. If you do not understand the code, ask for an explanation before changing it.

  2. Specify clearly. When asking for implementation, provide language, framework, constraints, and relevant code context.

  3. Review every output. Read the generated code. Check for correctness, style, and edge cases.

  4. Test immediately. Run tests or the application after each change. Catch issues early.

  5. Correct and iterate. If something is wrong, provide specific feedback. Small iterations beat big rewrites.

  6. Commit clean states. After a working change, commit. This gives you rollback points.

Summary

Pair programming with AI works best when you:

  • Stay in the driver's seat
  • Decide when to ask for explanation vs implementation
  • Keep architecture and design decisions yours
  • Iterate in small, reviewable steps
  • Correct the AI clearly when output is wrong

For more on getting value from AI without losing control, see AI-assisted coding: practical tips and When to use AI vs write it yourself.

Frequently Asked Questions

Pair programming with AI means treating the AI assistant as a collaborative partner. You stay in the driver's seat, deciding when to ask for explanations, suggestions, or implementations, while the AI helps with code and ideas.

Ask for explanations when you need to understand unfamiliar code, algorithms, or patterns. Ask for implementation when the task is well-defined and you know exactly what you want. Explanation first, implementation second.

Keep architecture and design decisions yours. Use AI for suggestions, not final decisions. Iterate in small steps. Review every output. Correct the AI when it is wrong rather than accepting blindly.

No. Let AI suggest implementations, but you choose the structure, modules, data flow, and dependencies. Treat AI proposals for big changes as suggestions to evaluate, not instructions to follow.

Work in small steps. Instead of 'rewrite this module,' try 'extract this function' or 'add a test for this case.' Small steps are easier to verify, easier to roll back, and keep you in control.

Related Posts