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.
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.
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:
- Wrong imports — referencing packages or modules that don't exist in your project
- Incorrect API calls — using methods or parameters that don't match the actual API
- Outdated syntax — using patterns from older versions of frameworks
- Hallucinated functions — inventing methods that look plausible but don't exist
- Subtly wrong logic — code that looks correct but has off-by-one errors or wrong comparisons
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.
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...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:
- Always share code context — Don't describe your code verbally when you can paste it. AI interprets actual code far more accurately than descriptions of code.
- Include error messages verbatim — Copy the full error, including stack traces. Don't paraphrase or summarize errors.
- State your intent explicitly — "I'm trying to make this component re-render only when the activity list changes" is far more useful than "this re-renders too much."
- Ask for alternatives — When you're unsure about an approach, ask for two or three options with trade-offs rather than a single solution.
- Give feedback on outputs — "This works but the naming is confusing" or "The approach is right but add error handling" helps AI learn what you need within the session.
Take a function or component you've recently written. Run through all three modes with AI:
- Brainstorm: Ask AI for three alternative approaches to the same problem. Compare with your implementation.
- Implement: Pick the most interesting alternative and ask AI to implement it.
- Review: Ask AI to review both versions — yours and the generated one — and identify strengths and weaknesses of each.
This exercise trains you to fluidly switch between modes, which is the foundation of effective AI pair programming.
Key Takeaways
- AI pair programming means collaboration — you direct, AI executes, you verify
- Master three modes: brainstorming (explore options), implementation (write code), and review (critique quality)
- The iterative loop (generate → test → improve → repeat) is the core workflow
- Work in small steps — one component, one function, one feature at a time
- Ask AI to explain its plan before writing code to catch design flaws early
- Always test AI output yourself — never trust code you haven't run
- Use AI as instant documentation and debug companion to stay in flow