Chapter 3

AI as a Pair Programmer

A useful mental model is to treat AI as a fallible pair-programming assistant, not a magic code generator. You provide direction, evidence, and judgment; the model can suggest options and drafts. This chapter shows how to keep that collaboration reviewable.

Last reviewed: Aug 28 2026


What Is Pair Programming?

Traditional pair programming involves two developers working at one machine. One plays the Driver — hands on keyboard, writing code. The other plays the Navigator — thinking strategically, spotting issues, and guiding direction. They swap roles regularly.

When you program with AI, the dynamic is similar but the roles shift:

Traditional Pair Programming

  • Driver — writes the code
  • Navigator — thinks strategically
  • Both are human, both understand the domain
  • Communication is natural and bidirectional

AI Pair Programming

  • You — the architect and decision-maker
  • AI — the fast, knowledgeable assistant
  • You own the vision; AI executes rapidly
  • Communication requires deliberate structure

The key insight is that AI doesn't write all the code for you. It means you collaborate — you think, AI generates, you evaluate, AI refines. The quality of output depends directly on the quality of your guidance.


Three Effective Working Modes

Different tasks benefit from different modes. The three modes below provide a practical starting toolkit; adapt them to the risk and evidence required by the task.

💡

1. Brainstorming Mode

Before writing a single line of code, ask AI to explore the solution space. This is where you generate options, compare approaches, and think through trade-offs — all before committing to an implementation direction.

Give me three different approaches to implement

real-time activity syncing in a React family planner.



For each approach, describe:

- How it works

- Pros and cons

- When you'd choose it
⚙️

2. Implementation Mode

Once you've decided on an approach, switch to implementation mode. Here you give AI specific, focused instructions to write code. Keep each request small — one component, one function, one feature at a time.

Implement approach #2 — WebSocket-based syncing.



Use TypeScript and React hooks.

Create a custom useActivitySync hook that:

- Connects to ws://localhost:3001

- Handles reconnection on disconnect

- Returns { activities, isConnected, error }
🔍

3. Review Mode

After generating code, switch AI into reviewer mode. Ask it to critique its own output — or your existing code — with the eye of a senior developer. This catches issues that generation mode often misses.

Review this code as a senior React developer.



Focus on:

- Performance issues (unnecessary re-renders)

- Error handling gaps

- TypeScript type safety

- Edge cases I might have missed



Be critical. I want honest feedback, not validation.

Pro Tip: Name Your Modes Explicitly

Naming the task mode can help set the expected output. Starting with "We're brainstorming — don't write code yet" or "Review this implementation" distinguishes exploration from implementation without relying on the model to infer your intent.


The Iterative Loop

The core rhythm of AI pair programming is not "ask once, get answer." It is a loop of generation, testing, review, and refinement, with a stopping condition based on acceptance criteria.

Describe goal
AI generates
You test
AI improves
Repeat
↺ Each cycle produces better code than the last

A feature may need several iterations before it is ready for review or release. Later cycles can fix bugs, add edge cases, improve types, and refine the design. The number and duration of those cycles depend on the task and the quality gates involved.

Core Principle

Prefer reviewable progress over prompt perfection. Provide enough context to make the first result testable, evaluate it, and refine only where the evidence shows a gap. High-risk tasks may require more requirements work before generation.


Work in Small Steps

A common mistake is to combine several dependent decisions in one request without defining interfaces or checks.

⚠️ Common Mistake

Build me a complete family

planner app with authentication,

database, real-time sync, and

a calendar view.

Result: chaotic, incomplete code that tries to do everything and does nothing well.

✅ Better Approach

  • First: build the calendar grid component
  • Then: add state management for activities
  • Then: connect to API
  • Then: add authentication
  • Then: add real-time sync

Result: each piece works correctly before you move on.

A focused task is easier to review. Large requests create more interacting assumptions; smaller coherent steps reduce that risk, provided you keep the relevant system context visible.


Ask for a Plan and Rationale

Before asking for code, ask for a concise plan, assumptions, and trade-offs. This can expose a weak design early and gives you something concrete to review.

Before writing any code, describe your plan:



- What components will you create?

- How will state flow between them?

- What are the potential edge cases?

- Are there any trade-offs in your approach?



Then implement the plan.

When the model states a plan, assumptions, and trade-offs, you can evaluate the approach before evaluating the code. Catching a flawed direction at this point can reduce later rework.


When AI Gets It Wrong

AI-generated code can be wrong even when it looks plausible. Plan checks for failure modes such as:

⚠️ Non-Negotiable Rule

Always test AI-generated code yourself. Never ship code you haven't run. Never assume correctness because "it looks right." The most dangerous bugs are the ones in code that appears perfectly reasonable. AI pair programming only works if you maintain your role as the quality gate.


AI as Instant Documentation

AI can help you navigate documentation by explaining terminology or suggesting what to look up. Treat the answer as a starting point, then verify version-sensitive APIs and behavior in the official documentation.

Explain the difference between useMemo and useCallback

in React.



When should I use each one?

Give me a concrete example where using the wrong one

would cause a performance problem.

Follow-up questions can help you identify the relevant concept or documentation section. For a question such as whether useMemo helps when filtering 500 activities, verify the current React guidance and measure the actual component before applying the suggestion.


AI as Debug Companion

When you hit an error, AI excels at rapid diagnosis — especially when you give it proper context. Here's the pattern:

Here is my code:



[paste the relevant function or component]



Error message:

TypeError: Cannot read properties of undefined (reading 'map')

  at ActivityList (ActivityList.tsx:23:18)



What I'm trying to do:

Render a list of activities passed as props.



What happens instead:

Crashes on initial render before data loads.



What's the most likely cause?

Notice the structure: code, exact error message, intent, and observed behavior. This gives AI everything it needs for accurate diagnosis. We'll go much deeper into debugging strategies in Chapter 5.


Real-World Conversation Flow

To make this concrete, here's what an actual pair programming session looks like in practice. Notice how the developer stays in control while leveraging AI's speed.

Scenario: Building an Activity Filter Component
You
I need a filter component for my family planner. Users should be able to filter activities by family member and by day of the week. Before writing code, describe your approach.
AI
I'd create a FilterBar component with two dropdown selectors. State would live in the parent via a callback. I'd use a FilterState interface with member: string | null and day: string | null. The parent applies filters to the activity list before passing to the calendar grid...
You
Good approach, but use multi-select for family members — users might want to see activities for 2-3 people at once. Implement it.
AI
[Generates FilterBar component with multi-select]
You
This works, but the multi-select dropdown doesn't show which members are currently selected. Add visual indicators — maybe chips/tags for selected members.
AI
[Adds chip-style selected member tags with remove buttons]
You
Now review this component for accessibility issues.

Notice the pattern: the developer directed each step, evaluated the output, and guided refinement. The model proposed; the developer decided and continued until the stated criteria were met.


Effective Communication Patterns

Over time, certain communication patterns consistently produce better results when pair programming with AI. These are worth making habitual:


🧪 Practical Exercise

Take a function or component you've recently written. Run through all three modes with AI:

This exercise trains you to fluidly switch between modes, which is the foundation of effective AI pair programming.


Key Takeaways

Related Guides

VS Code and Cursor with AI

Put pair-programming patterns into practice inside an editor.

CLI-First AI Development

Work with coding agents from the terminal on real projects.

Previous Chapter Writing Effective Prompts
Next Chapter From Idea to Code