Prompt Engineering for Code: Getting Better Output from Claude Code — Claude Skills 360 Blog
Blog / Productivity / Prompt Engineering for Code: Getting Better Output from Claude Code
Productivity

Prompt Engineering for Code: Getting Better Output from Claude Code

Published: September 12, 2026
Read time: 8 min read
By: Claude Skills 360

Claude Code understands code exceptionally well, but the quality of its output depends significantly on how you communicate what you want. Vague prompts produce generic code. Specific prompts with context produce code that fits your exact codebase. This guide covers the prompt patterns that consistently produce better results.

The Core Pattern: Context + Constraint + Criterion

Every effective Claude Code prompt has three elements:

Context: What exists, what it does, what conventions it follows
Constraint: What specifically needs to change
Criterion: How to judge whether it’s correct

❌ Vague: "Add error handling to the API"

✅ Specific:
Context: Express API using our custom AppError class (src/errors.ts).
Errors should use error codes from src/constants/errorCodes.ts.
Constraint: Add error handling to all route handlers in src/routes/orders.ts.
Criterion: Every handler should return AppError for validation failures,
not found errors, and auth failures. No raw Error objects or unhandled rejections.

The vague prompt produces generic try/catch. The specific prompt produces error handling that integrates with your existing patterns.

CLAUDE.md Design

CLAUDE.md is loaded at the start of every Claude Code session. It replaces context you’d otherwise have to repeat in every prompt.

What goes in CLAUDE.md

# Project: Order Management System

## Commands
- Dev: `npm run dev` (starts on :3000)
- Test: `npm test` (vitest, tests in __tests__/ parallel to source)
- Build: `npm run build && npm run type-check`
- Lint: `npm run lint` (ESLint + Prettier — run before commits)
- DB migrations: `npm run migrate` (knex, files in db/migrations/)

## Architecture
- Express + TypeScript, strict mode
- All DB queries in src/repositories/ — no SQL in controllers
- Controllers: src/controllers/ — parse req/res only, no business logic
- Business logic: src/services/ — pure functions where possible
- Validation: zod schemas in src/schemas/ — validate at the HTTP boundary

## Conventions
- Errors: always throw AppError with code from src/constants/errorCodes.ts
- Async: always async/await, never .then()
- Tests: full database integration tests (no mocking the DB layer)
- Logging: src/lib/logger.ts (pino) — structured JSON, never console.log

## Do not
- Commit directly to main (we use PRs)
- Run `git add -A` — use specific files
- Add console.log statements (use logger.ts)

The “Do not” section prevents common mistakes. Claude Code respects it.

CLAUDE.md for Teams

## Team Context
- Code reviewer: PR reviews look for test coverage, no N+1 queries, proper error codes
- Deployment: Heroku with Postgres — no filesystem writes outside /tmp
- Feature flags: use client.variation('flag-name', user, default) — see src/lib/featureFlags.ts
- Performance: any query that touches > 10k rows needs EXPLAIN ANALYZE approval

## Current Sprint Focus
- OAuth2 migration (replacing legacy session tokens) — see docs/oauth-migration.md
- When touching auth code: keep backward compatibility until auth-cleanup-Q3 flag removes old paths

Effective Task Decomposition

Complex tasks produce better results when broken into stages:

❌ One big prompt:
"Refactor the user authentication system to use JWT instead of sessions,
add refresh tokens, implement logout, and add 2FA support."

✅ Staged approach:
Stage 1: "Read src/auth/ and explain the current session-based auth flow."
Stage 2: "Replace session tokens with JWT for the /login endpoint only.
          Keep session code as fallback — don't delete it yet."
Stage 3: "Add JWT refresh tokens. Store in httpOnly cookie."
Stage 4: "Replace the session middleware with JWT middleware for protected routes."
Stage 5: "Remove the old session code and run the auth tests."

The staged approach lets you verify each step before proceeding. If stage 2 has issues, you catch them before the whole system is rewritten.

Working with Large Codebases

Prime the Context

Before we start: read src/billing/ completely.
I want you to understand the existing code before we change anything.

This prevents Claude Code from making incorrect assumptions and producing code that doesn’t match existing patterns.

Reference Specific Files

Add an invoice generation feature, following the same pattern as
src/billing/receipts.ts for the generation logic and
src/api/receipts.ts for the API endpoint.

Referencing existing patterns produces code that’s consistent with your codebase instead of generic code.

Working in Layers

First, write the TypeScript types for invoice generation (no implementation).
Don't write any logic yet — just the interfaces.

Define the interfaces first. Review them. Then implement. This catches design mistakes cheaply.

Prompts That Consistently Work

”Explain before you change”

Read src/jobs/emailQueue.ts and explain how it works before making any changes.

Forces Claude Code to build correct understanding before modifying code.

”Show the existing pattern, then apply it”

Show me how we currently handle pagination in src/api/products.ts,
then apply the same pattern to src/api/orders.ts.

Explicitly surfacing the existing pattern ensures consistency.

”What could go wrong?”

I'm about to add cascade deletes to the users → orders FK relationship.
What data integrity issues should I consider first?

Use Claude Code as a reviewer before implementing risky changes.

Test-first workflow

Write the tests for the new feature first (all failing).
Then implement the minimum code to make them pass.
Don't add anything not required by the tests.

Produces tight, well-tested implementations.

Debugging Prompts That Fail

Problem: Claude Code adds features you didn’t ask for

Fix: Add “Only change what I’ve asked. Don’t add error handling, refactoring, or improvements beyond the specific ask.”

Problem: Claude Code changes the wrong files

Fix: Start with “Only modify src/services/orders.ts. Do not touch anything else.” Then name the specific functions if needed.

Problem: Generated code doesn’t match your conventions

Fix: Before complex tasks, run: “Read the following files and describe the patterns you observe: [files].” Verify it understood, then proceed.

Problem: Claude Code keeps re-doing what you just undid

Fix: Use CLAUDE.md to document the constraint permanently. “Do not use X” in CLAUDE.md is persistent; saying it in a prompt is not.

Customizing Claude Code Behavior

Hooks for Automatic Actions

# .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint:fix -- ${file}"
          }
        ]
      }
    ]
  }
}

Every file Claude Code edits is automatically linted. No “and run the linter” needed in every prompt.

Custom Slash Commands

<!-- .claude/commands/review.md -->
Review the code I've written and check for:
1. TypeScript errors (`npx tsc --noEmit`)
2. ESLint violations (`npm run lint`)
3. Missing tests for new public functions
4. Any queries that might have N+1 issues
5. Hardcoded values that should be in config

Fix any issues found, then summarize what you changed.

Use with /review. Claude Code runs this workflow automatically.

Non-Obvious CLAUDE.md Patterns

## Context That Changes How Claude Code Works
- When I say "follow the existing pattern", check for the most recent file modified, not the oldest
- When adding new API endpoints, always add the OpenAPI comment above the route handler
- When writing migrations, always include an up and down function — even for data changes
- When I ask to "test" something, run the tests and show me the output before responding

These instructions adjust behavior for the quirks of your specific project.

For the complete guide to CLAUDE.md structure and all configurable settings, see the Claude.md guide. For hooks that automate actions in response to Claude Code file edits, see the hooks guide. The Claude Skills 360 bundle includes prompt engineering skill sets — 200+ tested prompts for common development tasks across frameworks. Start with the free tier to try the prompt patterns.

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free