The difference between frustrating AI coding sessions and productive ones often comes down to how you ask.
Same AI. Same task. Different prompts. Completely different results.
I’ve spent hundreds of hours refining my prompting approach. Here’s what actually works.
Why Prompts Matter So Much
AI coding tools are powerful but not psychic. They don’t know:
- What you’re actually trying to build
- Your project’s conventions and patterns
- What you’ve already tried
- Why you’re doing something a certain way
- What “good” means for your specific situation
Your prompt fills these gaps. A vague prompt forces the AI to guess. A precise prompt gets you usable code on the first try.
The goal isn’t to write perfect prompts every time. It’s to develop intuitions about what information helps and what’s just noise.
The Core Framework
Every effective coding prompt has three elements:
Context: What Claude needs to know about your situation Intent: What you’re trying to accomplish Constraints: What the solution needs to comply with
Bad prompts often miss one or more of these. Let’s look at each.
Context: Setting the Scene
Context is information about your project, codebase, and current state.
Bad prompt:
“Add a login button”
Good prompt:
“I’m building a React app with Tailwind CSS. My header component is in components/Header.tsx. I need to add a login button next to the navigation links.”
The good prompt tells Claude:
- The tech stack (React, Tailwind)
- The file structure (where Header lives)
- Where the button goes (next to navigation)
More context = fewer assumptions = better code.
What to include:
- Tech stack and major dependencies
- Relevant file names and their locations
- Current state of the code (what already exists)
- How this feature fits into the bigger picture
What not to include:
- Unrelated parts of your codebase
- History that doesn’t affect the current task
- Obvious things the AI can infer
Intent: What You Actually Want
Intent is the goal, not just the task.
Task-only prompt:
“Create a user table component”
Intent-rich prompt:
“Create a user table component. It will display a list of users fetched from our API. The table needs to be sortable by name and date, and each row should have an edit button that opens a modal.”
The second prompt explains why you need the table and what it needs to do. Now Claude can make better implementation decisions.
Techniques for clearer intent:
Explain the “why”:
“I need a loading state (because users are seeing a blank screen for 2 seconds while data loads)”
Describe the user experience:
“When someone clicks this button, they should see a confirmation modal, then the item should disappear with a fade animation”
Reference familiar patterns:
“Like how Gmail handles email deletion - soft delete with an undo option”
Constraints: Keeping It On Track
Constraints prevent Claude from going in directions you don’t want.
Unconstrained:
“Build a form for user signup”
Constrained:
“Build a signup form. Requirements: email and password fields only, no username. Use our existing FormInput component. Validation should happen on submit, not on blur. Error messages below each field.”
Constraints include:
- What to use (specific components, libraries)
- What to avoid (no Redux, no external dependencies)
- Style requirements (match existing patterns)
- Performance needs (must work offline, must load fast)
- Security requirements (never log passwords, sanitize inputs)
Practical Patterns
Here are prompting patterns I use constantly.
Pattern 1: The Specification Prompt
For complex features, write a mini-specification:
Build a comments feature with these requirements:
Data model:
- Comment has: id, author, content, timestamp, parentId (for replies)
- Store in Supabase, table name "comments"
UI:
- List of comments, newest first
- Each comment shows author, content, time
- Reply button on each comment
- Nested replies indented
Behavior:
- Real-time updates (Supabase subscriptions)
- Optimistic UI for new comments
- Loading states during submission
Constraints:
- Use existing Button and Avatar components
- Match the styling of the existing card components
This takes longer to write but saves multiple rounds of clarification.
Pattern 2: The Example-First Prompt
Show before you tell:
“I want the new UserCard to work like the existing ProductCard:
<ProductCard image={product.image} title={product.name} subtitle={product.category} onClick={() => selectProduct(product.id)} />But for users. Display avatar, name, role, and an onClick that selects the user.”
Examples are unambiguous. Claude can match the pattern exactly.
Pattern 3: The Incremental Prompt
Break big tasks into steps:
First prompt:
“Create the basic structure for a settings page with a sidebar and main content area.”
Second prompt:
“Now add navigation items to the sidebar: Account, Security, Notifications, Billing.”
Third prompt:
“Implement the Account section with a form for name, email, and profile photo.”
Each step builds on the previous. Easier for Claude to track. Easier for you to course-correct.
Pattern 4: The Fix Prompt
When something’s wrong, be specific:
Bad:
“This doesn’t work”
Good:
“When I click Submit, nothing happens. I expected the form to POST to /api/users. I see no network request in devtools. Here’s the current handleSubmit function: [paste code]”
Include:
- What you expected
- What actually happened
- Any error messages
- The relevant code
Pattern 5: The Refactor Prompt
For improving existing code:
“Refactor this function to be more readable. Currently it’s a 50-line function that fetches data, transforms it, and renders. Break it into smaller functions with clear names. Keep the same external behavior.”
Specify what “better” means: more readable? more efficient? more testable?
Advanced Techniques
Using CLAUDE.md Files
Create a CLAUDE.md file in your project root:
# Project: TaskFlow
## Stack
- Next.js 14 (App Router)
- TypeScript strict mode
- Tailwind CSS
- Prisma with PostgreSQL
## Conventions
- Components in /components, pages in /app
- Use "use client" only when necessary
- Prefer server components
- All database queries through /lib/db.ts
## Patterns
- Use React Query for client-side data
- Forms use react-hook-form with zod
- Toast notifications via sonner
## Do Not
- Install new dependencies without asking
- Use inline styles
- Skip TypeScript types
Claude reads this automatically. It becomes default context for every conversation.
Screenshot-Assisted Prompts
For UI work, screenshots are powerful:
“Here’s a screenshot of the current design. I need you to: 1) Add more spacing between the cards, 2) Make the text smaller on mobile, 3) Add a subtle border to each card.”
Visual context plus specific requests gets precise results.
Diff-Style Prompts
Show what you want to change:
“In the Header component, change the logo from text to an image. Here’s the current code:
<h1 className="text-xl font-bold">TaskFlow</h1>Replace with an Image component using /logo.png at 32x32 pixels.”
Point to exactly what changes and how.
Common Mistakes
Being too vague: “Make it better” gives Claude no direction.
Being too specific about implementation: “Use a for loop here” prevents Claude from choosing a better approach.
Pasting too much code: Share the relevant files, not your entire codebase.
Not providing error context: “It’s broken” is useless. Show the error message.
Expecting perfection on the first try: Plan to iterate. Start broad, refine narrow.
The 80/20 of Better Prompts
If you only remember four things:
- Include your tech stack - Claude can’t guess
- Explain what success looks like - Describe the end state
- Provide relevant code - Show what exists
- Constrain when necessary - Prevent unwanted directions
These four practices cover most cases. Everything else is refinement.
Master AI Coding
Learn the complete system for getting great results from AI coding tools.
Get the CourseBuilding Intuition
Good prompting is a skill. It develops with practice.
Pay attention to when Claude gets it right on the first try. What did your prompt include? Pay attention to when it misses the mark. What was ambiguous?
Over time, you’ll develop intuitions about what information helps and what’s noise. Your prompts will get shorter and more effective.
The investment pays off. Better prompts mean less frustration, faster development, and higher quality output. It’s one of the highest-leverage skills for vibe coding.
Start with the framework: context, intent, constraints. Refine from there.
The AI is capable. Your prompts unlock that capability.
