πŸ“š Learning Hub
Β· 4 min read

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

ToolTip
Claude CodeUse /compact with focus before complex prompts
CursorUse @file references instead of pasting code
AiderAdd only the files you’re editing to context
Codex CLIUse AGENTS.md for project-wide conventions
Gemini CLIUse @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