Prompt Engineering for AI Coding: Patterns That Actually Work (2026)
Most prompt engineering advice is for chatbots. Coding prompts are different β youβre working with files, constraints, existing code, and specific outcomes. Here are the patterns that actually improve AI coding output.
Pattern 1: Constraint-first prompting
Tell the AI what NOT to do before telling it what to do:
β Bad: "Add authentication to this app"
β
Good: "Add JWT authentication to this Express app.
Constraints:
- Don't modify existing routes
- Use the existing User model in src/models/user.ts
- Store tokens in httpOnly cookies, not localStorage
- Token expiration: 24 hours
- Use bcrypt for password hashing (already in package.json)"
Constraints prevent the AI from making assumptions that break your existing code. The more specific your constraints, the fewer iterations you need.
Pattern 2: Show the shape of the output
β Bad: "Write tests for the auth module"
β
Good: "Write tests for src/auth/middleware.ts using Vitest.
Follow this pattern:
describe('authMiddleware', () => {
it('should return 401 when no token provided', async () => {
// ... test here
});
it('should return 401 when token is expired', async () => {
// ... test here
});
it('should set req.user when token is valid', async () => {
// ... test here
});
});
Cover: missing token, expired token, invalid token, valid token.
Use the test helpers in src/test/helpers.ts for creating mock requests."
Showing the structure tells the AI exactly what format you expect. It fills in the implementation.
Pattern 3: Reference existing code
β Bad: "Create a new API endpoint for orders"
β
Good: "Create a new API endpoint for orders.
Follow the exact same pattern as src/routes/users.ts:
- Same error handling structure
- Same validation approach (Zod schemas)
- Same response format
- Same middleware chain
The Order model is in src/models/order.ts.
The Zod schema should validate: userId (string), items (array of {productId, quantity}), total (number)."
Referencing existing files gives the AI your projectβs conventions without you having to explain them.
Pattern 4: Iterative refinement
Donβt try to get everything in one prompt. Build up:
Prompt 1: "Create the basic Order model with TypeScript types"
Review β looks good
Prompt 2: "Now add the Zod validation schema for order creation"
Review β adjust one field
Prompt 3: "Create the POST /orders endpoint using the model and schema"
Review β done
Each step is small enough to review quickly. If something goes wrong, you only lose one step, not the whole feature.
Pattern 5: Explain the why
β Bad: "Refactor this function to use a Map instead of an object"
β
Good: "Refactor this function to use a Map instead of an object.
Reason: we're using numeric keys and need guaranteed insertion order.
The current implementation breaks when keys exceed 2^31 because
V8 converts large numeric object keys to strings."
When the AI understands why you want a change, it makes better decisions about edge cases and related code.
Pattern 6: The βfix and explainβ pattern
When debugging:
"This test is failing:
[paste test output]
The expected behavior is: when a user with role 'admin' calls DELETE /users/:id,
it should delete the user and return 204.
The actual behavior is: it returns 403 Forbidden.
Find the bug. Explain what's wrong before fixing it."
Asking the AI to explain before fixing prevents it from making random changes. If the explanation is wrong, you know the fix will be wrong too β and you can redirect.
Pattern 7: Scope limiting
β Bad: "Improve this codebase"
β
Good: "In src/auth/middleware.ts only:
1. Add rate limiting (max 5 login attempts per minute per IP)
2. Add request logging (log IP, timestamp, success/failure)
Don't modify any other files."
Unbounded prompts lead to unbounded changes. Always specify which files to touch and which to leave alone.
Anti-patterns to avoid
Donβt paste entire files and say βfix this.β Point to the specific problem area.
Donβt chain too many requests without reviewing. After 3-4 changes, review everything before continuing.
Donβt fight the AI. If it keeps doing something wrong after 2 attempts, rewind and try a completely different approach.
Donβt use AI for trivial changes. Renaming a variable or adding a comment is faster to do yourself than to prompt, wait, and review.
Tool-specific tips
| Tool | Tip |
|---|---|
| Claude Code | Use /compact with focus before complex prompts |
| Cursor | Use @file references instead of pasting code |
| Aider | Add only the files youβre editing to context |
| Codex CLI | Use AGENTS.md for project-wide conventions |
| Gemini CLI | Use @subagent for research before coding |
Related: Claude Code Cheat Sheet Β· Best AI Coding Tools Β· How to Use Claude Code Β· Aider Complete Guide Β· Long-Running AI Agents Β· Vibe Coding Complete Guide