How to write prompts that generate better code. Context-setting, spec-driven prompting, iterative refinement, and the patterns that produce production-ready code from AI.
Generating code requires more precision than generating text. A slightly wrong word in prose is forgivable; a slightly wrong variable name in code is a bug.
I'm building a [type of application] using [tech stack].
The codebase uses [patterns/conventions].
I need to [specific task].
Why it works: Models produce dramatically better code when they know the stack, conventions, and surrounding architecture.
Instead of describing what you want in prose, write a mini-spec:
## Function: calculateShippingCost
Input:
- items: Array of { weight: number (kg), dimensions: {l, w, h} (cm) }
- destination: { country: string, postalCode: string }
- shippingMethod: "standard" | "express" | "overnight"
Output:
- { cost: number, estimatedDays: number, carrier: string }
Behavior:
- Free shipping for orders over $100
- Express adds 50% to base cost
- Overnight adds 200% to base cost
- International orders add flat $15 surcharge
- Throw error if items array is empty
Constraints:
- TypeScript with strict types
- No external dependencies
- Include JSDoc comments
- Handle edge cases (max weight, oversized items)
Provide an example of existing code in your project:
Here's how we handle similar functions in this codebase:
// Example from our existing code:
export async function calculateTax(amount: number, state: string): Promise<TaxResult> {
// ... existing code ...
}
Now write a similar function for shipping cost calculation.
| Element | Impact | Example |
|---|---|---|
| Language/framework | Critical | "TypeScript with Next.js 16" |
| Existing patterns | High | "We use Prisma for DB access" |
| Input/output types | High | "Takes a UserDTO, returns a Promise<Result>" |
| Error handling | Medium | "Use Result type, no throw" |
| Testing | Medium | "Include Vitest test cases" |
| Performance | Situational | "Must handle 10K items efficiently" |
Describe your problem in detail — often the answer becomes obvious:
I have a race condition where two API calls can create duplicate users.
The flow is: 1) check if email exists, 2) if not, create user.
Between steps 1 and 2, another request can slip in.
What's the best way to handle this in PostgreSQL with Prisma?
Review this code for:
1. Security vulnerabilities
2. Performance issues
3. Error handling gaps
4. TypeScript type safety
[paste your code]
For each issue, explain WHY it's a problem and provide the fixed code.
Refactor this function to:
- Extract the validation logic into a separate function
- Replace the nested if/else with early returns
- Add proper TypeScript types (no 'any')
- Keep the same behavior (don't change the API)
[paste your code]
Convert this Express.js route handler to Next.js 16 App Router format:
- Keep the same logic
- Use the new Route Handler convention
- Adapt the middleware pattern
- Update the response format
[paste Express code]
Don't try to get everything in one prompt. Use a conversation:
| Model | Strongest At |
|---|---|
| Claude Opus/Sonnet | Large codebase understanding, refactoring, architecture decisions |
| GPT-4o / GPT-5 | Quick code generation, API integration, broad language support |
| Gemini 2.5 Pro | Long-context code analysis, documentation, multi-file understanding |
| Copilot | Inline completion, boilerplate, test generation |
| Cursor | Full-file edits, codebase-aware suggestions |
Sign in to join the discussion.
No comments yet. Share your thoughts on this article.