Claude Code Best Practices: 10 Prompting Patterns That Actually Work
Most developers use Claude Code like a chatbot. Here are 10 prompting patterns — with real examples — that turn it into a 10x engineering force multiplier.
Most developers type something like "add a login page" into Claude Code and then complain the output is generic.
The problem isn't the model. It's the prompt.
Claude Code is an agent — it reads your entire codebase, runs commands, and makes decisions. But agents are only as good as their instructions. Vague instructions produce vague results. Specific instructions produce specific, codebase-aware results.
Here are 10 prompting patterns that consistently produce better output, tested across dozens of projects.
Pattern 1: Reference existing patterns explicitly
Bad: "Add a new API route for user preferences."
Good: "Add a new API route for user preferences. Follow the exact patterns in app/api/stripe/checkout/route.ts — same error handling, same response format, same auth check."
Why it works: Claude Code reads your whole repo, but it doesn't know which files represent your preferred patterns. When you point to a specific file, it matches the style exactly — imports, error handling, response shape, everything.
Pattern 2: Describe the outcome, not the steps
Bad: "Create a file called UserPrefs.tsx. Import useState. Add a form with three fields..."
Good: "Users need to set their email notification preferences — daily digest, weekly summary, or none. When they save, it should update via our existing API pattern and show a success toast."
Why it works: When you dictate steps, you're limiting Claude Code to your plan. When you describe outcomes, it chooses the best implementation using the patterns already in your codebase. It often finds better approaches than you would have prescribed.
Pattern 3: The constraint sandwich
Structure: desired outcome + constraints + quality bar.
Example: "Add dark mode support to the settings page. Constraints: use our existing ThemeProvider (don't create a new one), keep the same Tailwind classes we use elsewhere, don't touch any component outside app/settings/. The result should look intentional — not like someone just inverted the colors."
Why it works: Constraints prevent scope creep. The quality bar prevents lazy outputs. Without constraints, Claude Code might refactor your entire theme system when all you wanted was one page.
Pattern 4: Ask it to read before it writes
Example: "Before making any changes, read through the entire app/components/ui/ directory and app/lib/utils.ts. Understand what utilities and components already exist. Then add a reusable confirmation dialog that follows the same patterns."
Why it works: Claude Code will read files if relevant, but sometimes it rushes to write. Explicitly asking it to read first ensures it discovers existing utilities instead of reinventing them. This dramatically reduces duplicate code.
Pattern 5: The "fix it like a senior engineer" frame
Example: "Run the test suite. For every failing test, fix the underlying code — don't modify the tests. If a test is genuinely wrong, explain why before changing it."
Why it works: Without this frame, Claude Code often "fixes" failing tests by making the tests match the broken code. The senior engineer frame sets the right priority: tests define correctness, code should match.
Pattern 6: Incremental scope with checkpoints
Bad: "Build a complete user dashboard with analytics, settings, billing, and team management."
Good: "Let's build the user dashboard in steps. Start with just the analytics tab — show a chart of daily active usage from our existing /api/analytics endpoint. Commit when it works. I'll review before we move to the next tab."
Why it works: Large scope = large risk of going off track. By checkpointing, you review after each piece. If step 1 goes sideways, you've lost 5 minutes, not 30. Claude Code handles commits natively, so checkpointing is free.
Pattern 7: Give it the "why"
Bad: "Add rate limiting to the API."
Good: "We're getting hit by scrapers on /api/public/courses — 10K requests/min from single IPs. Add rate limiting to all /api/public/ routes. We're on Vercel, so it needs to work with edge functions. We don't want to add Redis for this — use in-memory or Vercel's built-in if available."
Why it works: The "why" gives Claude Code decision-making context. It knows this is about scrapers (not general rate limiting), it knows the deployment target (Vercel edge), and it knows the infrastructure constraint (no Redis). Every decision it makes will be better.
Pattern 8: The migration pattern
Example: "We're migrating from pages/ router to app/ router in Next.js. Take pages/api/auth/[...nextauth].ts and rewrite it as an app/api/auth/[...nextauth]/route.ts. Keep the exact same behavior and auth providers. Run the existing auth tests after migration to verify nothing broke."
Why it works: Migrations have a clear before/after. By giving Claude Code the source file, the target pattern, and a verification step (run tests), you get a reliable migration with built-in validation.
Pattern 9: Debug with context, not just symptoms
Bad: "The login page is broken."
Good: "After deploying commit abc123, users clicking 'Sign In' get a blank page. No errors in the browser console. The Supabase auth callback at /auth/callback returns 200 but the redirect doesn't fire. Check if the auth callback route is handling the code exchange correctly and if the redirect URL matches our NEXT_PUBLIC_SITE_URL."
Why it works: Debugging requires context. The more you narrow the problem — what changed, what the symptoms are, where you've already looked — the faster Claude Code converges on the fix. "It's broken" triggers a shotgun approach. Specifics trigger surgical fixes.
Pattern 10: The refactor with safety net
Example: "Refactor lib/resend.ts to split the email templates into separate files under lib/emails/. Keep the same public API — every function that's currently exported should still be importable from lib/resend.ts (re-export from the new files). Run the build and tests after to make sure nothing breaks."
Why it works: Refactors are scary because they can break things silently. By specifying the safety net (same public API, run build + tests), you get the refactor and the confidence it didn't break anything.
Bonus: The CLAUDE.md File
The highest-leverage thing you can do isn't a prompt — it's a CLAUDE.md file at your project root. This is a persistent instruction file that Claude Code reads automatically every session.
# CLAUDE.md
## Project
Next.js 14 app router, TypeScript, Tailwind, Supabase, Stripe.
## Patterns
- API routes: see app/api/stripe/checkout/route.ts as reference
- Components: use Radix primitives from components/ui/
- Always use server components unless client interactivity is needed
- Error handling: throw typed errors, catch in error.tsx boundaries
## Don'ts
- Don't install new dependencies without asking
- Don't modify middleware.ts without explicit approval
- Don't change any Stripe webhook handling without confirmation
This eliminates 50% of the context you'd otherwise repeat in every prompt.
The Meta-Pattern
All 10 patterns share one principle: treat Claude Code like a talented new hire on day one.
A talented new hire can write great code — but they don't know your codebase yet. They don't know your preferences. They don't know the weird legacy thing that breaks if you touch that file.
When you give context, constraints, and verification steps, you're onboarding that new hire. The better the onboarding, the better the output.
If you want to see these patterns in action with real projects, join AI Builder Club. We share prompts, CLAUDE.md files, and before/after comparisons from real codebases.
Get the free AI Builder Newsletter
Weekly deep-dives on AI tools, automation workflows, and builder strategies. Join 5,000+ readers.
No spam. Unsubscribe anytime.
Go deeper with AI Builder Club
Join 1,000+ ambitious professionals and builders learning to use AI at work.
- ✓Expert-led courses on Cursor, MCP, AI agents, and more
- ✓Weekly live workshops with industry builders
- ✓Private community for feedback, collaboration, and accountability