Chapter 3

AI as a Pair Programmer

AI works best when you treat it as a pair programming partner — not a magic code generator. That means you work together: you bring direction and judgment, AI brings speed and breadth. This chapter teaches you how to make that collaboration effective.


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

Skilled developers don't use AI the same way every time. They switch between distinct modes depending on what the task demands. Mastering these three modes gives you a flexible toolkit for any situation.

💡

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

Telling AI which mode you're in dramatically improves results. Starting a prompt with "We're in brainstorming mode — don't write code yet" or "Switch to review mode" gives the AI a clear frame for the kind of output you expect. Without this signal, AI tends to default to implementation mode, jumping straight to code even when you want high-level analysis.


The Iterative Loop

The core rhythm of AI pair programming isn't "ask once, get answer." It's a continuous loop of generation, testing, and refinement. This loop is the single most important pattern to internalize.

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

A typical feature might go through three to five iterations before it's production-ready. The first generation establishes the structure, subsequent iterations fix bugs, add edge cases, improve types, and refine the architecture. Each cycle is fast — often just a minute or two.

Core Principle

Speed of iteration beats quality of first attempt. Don't spend 20 minutes crafting a perfect prompt. Spend 2 minutes on a good-enough prompt, evaluate the output, and iterate. Three fast cycles beats one slow one almost every time.


Work in Small Steps

This is perhaps the most common mistake beginners make with AI pair programming — and the fix is simple.

⚠️ 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.

AI generates its best output when focused on a single, well-defined task. When you ask for too much at once, the context becomes muddled and the AI has to make assumptions about dozens of interconnected decisions simultaneously. Small steps eliminate this problem entirely.


Ask AI to Think Out Loud

One of the most underused pair programming techniques is asking AI to explain its reasoning before writing code. This serves two purposes: it helps you catch bad design decisions before they become code, and it helps you learn.

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 AI explains its reasoning, you can evaluate the approach before evaluating the code. If the plan has a flaw, you can redirect before a single line is written. This saves enormous amounts of time compared to debugging a flawed implementation.


When AI Gets It Wrong

AI will get things wrong. This isn't occasional — it's regular. Skilled pair programmers expect this and have strategies ready. The most common AI errors in code generation:

⚠️ 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

One of the most productive uses of AI as a pair programmer is replacing context-switching to documentation sites. Instead of leaving your editor, opening a browser, searching, finding the right page, and reading through examples — just ask.

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.

This isn't just faster than searching documentation — it's often better, because you can ask follow-up questions tailored to your specific situation. "Would useMemo help in my case where I'm filtering a list of 500 activities?" gets you a more useful answer than any generic docs page.


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 AI never made architectural decisions alone — it proposed, the developer decided, and iteration continued until the result was right.


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

Previous Chapter Writing Effective Prompts
Next Chapter From Idea to Code