Blog

Claude Code Prompting Guide

How to write prompts that get Claude Code to do exactly what you want — specificity, acceptance criteria, constraints, and the patterns that produce production-ready output.

Phos Team ·
claude code

Prompting Claude Code is not the same as prompting Claude.ai. When you use Claude.ai, the model generates text. When you use Claude Code, the model reads your files, writes code, and executes commands. A vague prompt in Claude.ai produces a vague answer. A vague prompt in Claude Code produces a change to your codebase that you then have to review and potentially undo.

Precision is not optional here. This guide shows you how to write prompts that produce accurate, production-ready output from the first attempt.


Why Claude Code Prompting Is Different

Claude.ai conversations are low-stakes. If the response is off-target, you ask again. Claude Code actions have consequences: files get edited, dependencies get installed, tests get modified.

Claude Code also has access to your actual codebase. It can read any file, understand your existing patterns, and make changes that propagate across multiple files. This makes it more powerful, and more consequential, than a chat-based assistant.

The other key difference is execution context. Claude Code knows which files exist, what they contain, and how they relate to each other. Your prompts do not need to explain what your code does. They need to specify what you want changed and what constraints apply.

Prompting Claude Code is closer to writing a ticket for a developer than having a conversation. The more specific the ticket, the better the output.


The Anatomy of a Good Claude Code Prompt

Every effective Claude Code prompt has four components:

  1. Task: What to do, stated as an action verb
  2. Context: Which file or directory, and any relevant background
  3. Constraints: What not to touch, what patterns to follow
  4. Acceptance criteria: How you will know it worked

You do not need a paragraph for each. Most good prompts are 2 to 4 sentences. What matters is that all four components are present.

The Template

In [file/directory], [action verb] such that [acceptance criteria]. 
Do not [constraint]. Use [pattern/convention] for [specific aspect].

Example:

In src/api/users.js, add input validation to the createUser function 
such that it returns a 400 error with a descriptive message if name or 
email is missing or invalid. Do not modify the database call. 
Use Joi for validation to match the pattern in src/api/products.js.

This prompt specifies the file, the function, the behavior, the error shape, the constraint (do not touch the DB call), and the convention to follow (look at products.js).


The Specificity Rule

Vague prompts produce guesses. Specific prompts produce precision.

Compare these two prompts:

Bad: "Add error handling to the API"

Good:

In src/api/orders.js, wrap the database calls in try/catch blocks. Return a 500 response 
with { error: 'Internal server error', requestId: req.id } on any database error. 
Do not modify the route handler signatures.

The vague version forces Claude Code to make assumptions about which API, which error handling pattern, and what the response shape should be. Every assumption is a potential mismatch with your existing code. The specific version eliminates all ambiguity.


6 Prompt Patterns with Before/After Examples

Pattern 1: Refactoring

Refactoring prompts need to specify the target structure, the files to touch, and a clear constraint that existing behavior must not change.

Bad:

Refactor the auth code to be cleaner

Good:

Refactor src/middleware/auth.js to extract the token validation logic 
into a separate function called validateToken. The function should accept 
a token string and return { valid: boolean, userId: string | null }. 
Do not change the middleware function signature or the error response shapes. 
All existing tests in tests/auth.test.js should still pass after the refactor.

Pattern 2: New Feature

New feature prompts need a complete description of inputs, outputs, and how the feature integrates with existing code.

Bad:

Add a search endpoint

Good:

In src/routes/products.js, add a GET /products/search endpoint that accepts 
a q query parameter and returns products where name contains the query string 
(case-insensitive). Return the same shape as the GET /products response. 
Use the existing db.query pattern from the list endpoint. 
Return an empty array (not a 404) when no results are found.

Pattern 3: Test Writing

Test writing prompts need to specify the test framework, what scenarios to cover, and where to put the test file.

Bad:

Write tests for the user service

Good:

Write Jest unit tests for src/services/userService.js in tests/unit/userService.test.js. 
Cover: createUser with valid input, createUser with missing email (should throw), 
getUserById with a valid ID, and getUserById with a nonexistent ID (should return null). 
Mock the database module at src/db/index.js. Follow the pattern in tests/unit/productService.test.js.

Pattern 4: Bug Fix

Bug fix prompts need a description of the observed behavior, the expected behavior, and where you think the issue is.

Bad:

The login is broken, fix it

Good:

In src/api/auth.js, the login endpoint returns a 500 error when the user's 
email contains uppercase letters. It should be case-insensitive. 
The issue is likely in the database query on line 34 where the email is not 
being lowercased before comparison. Fix the query so that login works 
regardless of the case of the email provided.

Pattern 5: Documentation

Documentation prompts need to specify the format, the audience, and which functions or modules to cover.

Bad:

Add documentation to the codebase

Good:

Add JSDoc comments to all exported functions in src/services/emailService.js. 
Include @param types and descriptions, @returns type and description, 
and @throws for any errors the function intentionally throws. 
Do not add comments to private helper functions. 
Follow the JSDoc style already used in src/services/userService.js.

Pattern 6: Migration

Migration prompts are the highest-stakes and need the most detail:

  • what you are migrating from
  • what you are migrating to
  • which files are in scope
  • what must not change

Bad:

Migrate from callbacks to async/await

Good:

In src/routes/ only, convert callback-style database calls to async/await. 
Each route function should become async. Wrap async operations in try/catch 
and pass errors to the Express next() handler. Do not touch src/services/ 
or src/middleware/ in this pass. Run the existing integration tests after 
each file to confirm nothing breaks.

What Goes in the Prompt vs What Goes in CLAUDE.md

This is a decision you will make dozens of times per project. The rule is straightforward:

Put in CLAUDE.md: Information that is true for every task in this project:

  • Stack and dependencies
  • Coding conventions
  • Testing framework
  • “Do not touch” files
  • Folder structure and environment setup

Put in the prompt: Information specific to this particular task:

  • The exact function to change
  • The behavior you want
  • Acceptance criteria for this change
  • Constraints specific to this change

If you find yourself repeating the same instruction across multiple prompts (e.g., "always use TypeScript" or "always use Jest for tests"), that instruction belongs in CLAUDE.md.

Context TypeCLAUDE.mdPrompt
Stack and dependenciesYesNo
Coding conventionsYesNo
Test frameworkYesNo
Which file to changeNoYes
Acceptance criteriaNoYes
Task-specific constraintsNoYes
Project-wide constraintsYesNo

Using /plan to Verify Intent Before Execution

After writing a prompt, especially for a complex task, run /plan before letting Claude Code execute. The plan shows you exactly which files will be touched and what changes are proposed.

Review the plan with your acceptance criteria in mind:

  • Does the plan include the changes you asked for?
  • Does it include any changes you did not ask for?
  • Are any “do not touch” files in the plan?

If the plan looks wrong, clarify before approving. It is faster to refine a prompt than to revert a set of changes across five files.

A plan that does not match your intent is useful information. It tells you exactly what was ambiguous in your prompt, which you can fix before any code changes.



The Investment in Better Prompts

Writing specific prompts takes slightly longer than writing vague ones. The payoff is real: fewer revisions, less code review time, and changes that match your conventions on the first pass.

If your team is learning Claude Code and wants to build these practices into your development workflow systematically, Phos can help. We are a CCA-F certified Claude partner with 400+ AI engagements.

Talk to the Phos team to learn how we help engineering teams get consistent, production-quality output from Claude Code.


FAQ

How long should a prompt be?

Most effective prompts are 3 to 6 sentences. Longer is not better. More specific is better. If your prompt is more than 10 sentences, some of that context probably belongs in CLAUDE.md rather than the prompt.

Should I include the code I want Claude Code to modify in the prompt?

No. Claude Code can read the file directly. You do not need to paste code into the prompt. Reference the file and function by name and Claude Code will read it. Pasting code into prompts adds tokens and can confuse Claude Code about whether you want it to use the pasted version or the actual file.

What if Claude Code does something I did not expect even with a specific prompt?

There are three things to check:

  1. Check whether CLAUDE.md contains a conflicting instruction. Claude Code follows CLAUDE.md instructions alongside prompt instructions, and they can conflict.
  2. Review the plan next time using /plan before executing.
  3. Add a "Do not" line to your prompt for the unexpected behavior, e.g., "Do not create new files unless explicitly asked."

Does it matter which verb I use to start a task prompt?

Yes, more than you might expect. Each verb carries a distinct intent:

  • "Add", create something new
  • "Update", modify something existing
  • "Refactor", restructure without changing behavior
  • "Replace", substitute one thing for another

Using the precise verb eliminates an entire category of ambiguity about whether Claude Code should create, modify, or delete.

Related articles

The fastest way to know whether we're the right fit, is a conversation.

STEP 1/2 · ABOUT YOU