Building a full-stack app with AI pair programming

Ray37 Intermediate 4h ago 495 views 12 likes 4 min read

Most people treat AI coding tools like a search engine with a chat box. They ask "How do I center a div?" or "Write a function to fetch data," copy the snippet, and pray it doesn't break the rest of the project. That is not pair programming; that is just using a fancy clipboard.

Real AI pair programming is about maintaining a shared state between your brain and the LLM. If you don't feed the AI the right context, you'll spend four hours debugging a hallucinated library version that hasn't existed since 2022.

I tried building a simple Task Tracker last Tuesday. I used Cursor (which is basically VS Code on steroids) and Claude 3.5 Sonnet. The goal was to move from a blank folder to a deployed app in under an hour.

Setting up the workspace for context

The biggest mistake beginners make is starting a chat without providing a roadmap. If you just say "Build me a task app," the AI will guess your tech stack. It might give you Tailwind CSS when you wanted Bootstrap, or use an outdated Next.js API route structure.

First, create a .cursorrules file (or a project-level instruction file) in your root directory. This forces the AI to stick to your specific stack.

// .cursorrules
You are an expert Full-stack TypeScript developer.
Tech Stack: 
- Frontend: Next.js 14 (App Router), Tailwind CSS, Shadcn UI
- Backend: Supabase (Auth and Database)
- State Management: Zustand

Coding Style:
- Use functional components and arrow functions.
- Strictly use TypeScript interfaces; avoid 'any'.
- Implement error handling for all async calls using try/catch blocks.
- Keep components small and modular.

With this file in place, the AI stops guessing. It knows exactly which version of Next.js to use.

The "Iterative Prompting" loop

Don't ask for the whole app at once. You'll get generic, buggy code. Instead, build in "vertical slices."

Step 1: The Schema
I started by defining the data. I didn't write the SQL; I asked the AI to generate the Supabase migration script.

Prompt: Based on the .cursorrules, generate a SQL migration for a 'tasks' table. I need id (uuid), created_at, title (text), is_completed (boolean), and user_id (uuid referencing auth.users).

Step 2: The Logic
Once the DB was live, I needed the fetch logic. Instead of writing the function, I highlighted the empty page.tsx file and used the "Composer" feature (Cmd+I in Cursor) to generate the server component.

// This is what the AI generated after I provided the Supabase schema
import { createClient } from '@/utils/supabase/server';

export default async function TasksPage() {
  const supabase = createClient();
  const { data: tasks, error } = await supabase.from('tasks').select('*');

  if (error) return <div>Error loading tasks: {error.message}</div>;

  return (
    <div className="p-6 max-w-md mx-auto">
      <h1 className="text-2xl font-bold mb-4">My Tasks</h1>
      <ul className="space-y-2">
        {tasks?.map(task => (
          <li key={task.id} className="p-2 border rounded shadow-sm">
            {task.title}
          </li>
        ))}
      </ul>
    </div>
  );
}

AI pair programming, AI beginner community

When the AI hits a wall

At 2:15 PM, I hit a snag. The AI kept trying to use a client-side hook in a server component. It kept suggesting useEffect, which threw a "useState/useEffect only works in Client Components" error.

This is where most beginners panic. They just paste the error and ask "Why isn't this working?"

The fix is to be prescriptive. I told it: "You are attempting to use a client hook in a Server Component. Refactor the list item into a separate Client Component called TaskItem.tsx and pass the task data as a prop."

Immediately, the AI restructured the folder:

  • app/page.tsx (Server) → fetches data.
  • components/TaskItem.tsx (Client) → handles the checkbox toggle.
Building a full-stack app with AI pair programming

| Approach | Result | Dev Time |
| :--- | :--- | :--- |
| "Fix this error" | 3-4 hallucinations, repetitive bugs | 45 mins |
| "Refactor to Client Component" | Correct architecture on first try | 2 mins |

Scaling your skills through community

You can't learn this in a vacuum. You'll eventually run into a weird edge case—like a specific MCP (Model Context Protocol) server crashing or a prompt that works in Claude but fails in GPT-4o—and you'll feel like you're shouting into a void.

This is why joining an AI beginner community is non-negotiable. You need a place to see how other devs are structuring their prompts and which tools are actually delivering. For example, checking out Prompt Sharing can show you exactly how a senior dev prompts for a complex React hook, saving you the trial-and-error phase.

The "magic" isn't in the model; it's in the workflow.

Refining the prompt for production

Once the basic app worked, I wanted to add a "Priority" tag. If you just say "add priority," the AI might just add a text field. To get it right, I used a structured prompt:

Prompt: Update the 'tasks' table to include a 'priority' column (enum: low, medium, high). Update the UI to show a colored badge based on the priority: low = gray, medium = yellow, high = red. Use Shadcn UI's Badge component.

This is the difference between a prototype and a product. Specificity kills bugs.

If you're still struggling with the setup, browsing through established Resources can help you find the right boilerplates so you aren't starting from zero every single time.

The final reality check

AI pair programming doesn't replace the need to understand the code. If you blindly accept every suggestion, you're building a house of cards.

Last week, the AI suggested a library for date formatting that was deprecated. Because I didn't check the documentation, I spent twenty minutes wondering why the build was failing.

My advice? Treat the AI as a very fast, slightly overconfident junior developer. Review every line. Question the architecture. If it suggests a library you've never heard of, go check its GitHub stars and last commit date before you npm install.

That's how you actually ship.

All Replies (0)

No replies yet — be the first!

Write a Reply

Markdown supported