# Building a full-stack app with AI pair programming

> Source: <https://promptcube3.com/en/threads/6684/>
> Published: 2026-08-17 14:37:49+00:00

# Building a full-stack app with AI pair programming

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](/en/tags/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.

``` js
// 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>
  );
}
```

### 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.

| 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](/en/tags/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](/en/category/prompts/) 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](/en/category/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.

[Next Can we actually handle a full video pipeline in the browser →](/en/threads/6586/)

## All Replies （0）

No replies yet — be the first!
