Prompt Engineering for Developers: Get Better Code From AI
Vague prompts produce vague code. Here's a systematic approach to writing prompts that consistently produce high-quality, maintainable code from AI tools.
Why Your AI Code Quality Is a Prompt Quality Problem
Most developers blame AI tools for producing bad code. The real culprit is the prompt. 'Build me a login page' is not a specification — it's a vague wish. AI fills in the gaps with assumptions, and those assumptions are often wrong for your context. A well-engineered prompt provides context, constraints, and explicit requirements. The output quality difference between a vague prompt and a well-structured prompt is significant — often the difference between prototype-quality and production-quality code.
The Anatomy of a High-Quality Code Prompt
A good code prompt has five components. Context: what system is this part of? What technologies are you using? Task: what specific thing do you need the code to do? Constraints: what must it NOT do, what edge cases matter, what performance requirements exist? Output format: TypeScript? With types? With tests? With error handling? Examples: input/output examples or existing code patterns to follow. Most developers provide only the task. The other four components are what produce good code.
// Vague prompt (what most people write):
// 'Write a function to filter users'
// High-quality prompt:
/*
Context: I'm building a user management API in Node/TypeScript using Prisma
with a PostgreSQL database. Users have fields: id, email, role (enum: admin/user/viewer),
createdAt, status (enum: active/inactive/suspended).
Task: Write a filterUsers function that accepts filter criteria and returns
a paginated list of users.
Constraints:
- Must support filtering by role, status, and date range (createdAt)
- Pagination via cursor (not offset) for performance
- Must be type-safe (TypeScript generics where appropriate)
- Include input validation with descriptive error messages
- No raw SQL — use Prisma query builder
Output: TypeScript function with full types, error handling, and a JSDoc comment.
Include a brief comment explaining the cursor pagination choice.
*/
// The output quality difference is dramatic.Chain-of-Thought Prompting for Complex Problems
For complex architectural or algorithmic problems, ask the AI to reason before generating code. 'Think through the approach step-by-step before writing any code. What are the trade-offs of different approaches?' This chain-of-thought technique produces significantly better results for complex problems because it forces the model to generate reasoning before output. The same way a senior engineer sketches architecture before coding, this prompt structure encourages the AI to plan before generating.
// Chain-of-thought prompt example:
/*
I need to implement rate limiting for my API. Before writing any code,
think through:
1. What rate limiting algorithms exist (token bucket, leaky bucket, fixed window, sliding window)?
2. What are the trade-offs of each for a REST API?
3. What's the simplest implementation that's also correct?
4. What edge cases matter for a multi-server deployment?
Then recommend an approach and implement it.
*/
// This produces architecture reasoning + implementation,
// rather than just the first implementation that comes to mind.When to Use Iterative Prompting
Complex features rarely emerge from a single prompt. Instead, treat AI assistance as an iterative process: start with the interface/types, then the core logic, then error handling, then tests. Each prompt builds on the previous output. 'Given the type definitions above, implement the core function.' 'Given this implementation, write unit tests that cover the edge cases we discussed.' 'Review this implementation for security vulnerabilities.' This iterative approach produces better-integrated code and lets you validate each layer before building the next.
Building a Prompt Library
Senior engineers using AI tools maintain a library of prompts that reliably produce good output for their specific stack. If you're building a TypeScript/React/Node app, there's a finite set of prompts you'll want consistently: 'add authentication middleware to this Express route', 'generate a Prisma migration for these schema changes', 'write a React hook that...' Over time these prompts get refined until they reliably produce what you want. The Prompt Engineering for Developers module at Beyond Vibe Code walks through building exactly this kind of personal prompt library.