Prompt Engineering for Developers — Get Better Code from AI

Master the art of writing effective prompts for AI coding assistants. Learn techniques that will transform your AI interactions.

Published
Author Basil
prompt engineeringaicursorclaudetips

Why Prompt Engineering Matters

The difference between a mediocre AI response and an excellent one often comes down to how you ask. Good prompt engineering can:

  • Reduce iterations — Get working code in fewer tries
  • Improve quality — Get cleaner, more maintainable code
  • Save time — Less back-and-forth fixing issues
  • Unlock capabilities — Access advanced features you didn’t know existed

This guide covers practical techniques you can use immediately with any AI coding assistant.


The Basic Structure

A Good Prompt Has Four Parts

  1. Context — What you’re working on
  2. Task — What you want the AI to do
  3. Constraints — Any specific requirements
  4. Format — How you want the output

Template

[Context]
I'm working on a React e-commerce app with TypeScript and Tailwind.

[Task]
Create a shopping cart component that displays added items.

[Constraints]
- Show product image, name, price, and quantity
- Include +/- buttons to adjust quantity
- Show total price at the bottom
- Use the existing theme colors

[Format]
React functional component with TypeScript

Technique 1: Provide Context

Bad Prompt

Create a button component

Good Prompt

Create a button component for a SaaS dashboard. The design system uses:
- Primary color: #4F46E5 (indigo-600)
- Border radius: 8px
- Font: Inter
- Sizes: sm (32px), md (40px), lg (48px)
- States: default, hover (darken 10%), active (darken 15%), disabled (50% opacity)

Why It Works

The AI understands your constraints and generates code that fits your existing design system.


Technique 2: Show, Don’t Just Tell

Bad Prompt

Add error handling to this API call

Good Prompt

Add error handling to this API call. Follow this pattern from our codebase:

// In src/lib/api.ts, we handle errors like:
try {
  const data = await fetchData();
  return { success: true, data };
} catch (error) {
  if (error instanceof ValidationError) {
    return { success: false, error: error.message };
  }
  console.error('API Error:', error);
  return { success: false, error: 'Something went wrong' };
}

Apply this same pattern to the userService.ts file

Why It Works

Providing examples of your existing patterns ensures the AI generates consistent, idiomatic code.


Technique 3: Break Down Complex Tasks

Bad Prompt

Build a complete authentication system with email/password login, OAuth with Google and GitHub, password reset, email verification, session management, and protected routes

This is too much! The AI will either fail or produce shallow code.

Good Prompt (Iterative)

Prompt 1:

Create a basic authentication system with:
- User model with email and password_hash fields
- Register endpoint that validates email format and password strength
- Login endpoint that returns a JWT token

Prompt 2:

Add OAuth login with Google. Use NextAuth.js with these constraints:
- Use the existing user table
- Link OAuth accounts to existing users by email
- Store provider info in a separate table

Prompt 3:

Add password reset functionality:
- Forgot password page with email input
- Send reset email (mock the email sending for now)
- Reset password page with new password input
- Validate password strength (min 8 chars, 1 number, 1 special char)

Why It Works

Breaking complex tasks into smaller, focused prompts produces higher quality code.


Technique 4: Specify the “Don’ts”

Bad Prompt

Make this function faster

The AI might make changes you don’t want.

Good Prompt

Optimize this function for performance. Do NOT:
- Remove type safety
- Change the public API
- Use unsafe methods like innerHTML
- Remove error handling

DO:
- Use memoization where appropriate
- Optimize database queries
- Add caching

Why It Works

Explicitly stating constraints prevents unwanted changes and guides the AI toward solutions that fit your needs.


Technique 5: Use Role Playing

Bad Prompt

Write tests for this component

Good Prompt

Act as a senior React developer and TDD practitioner. Write tests for this component:
1. First, analyze the component's functionality
2. Write tests that cover:
   - Happy path (normal usage)
   - Edge cases (empty state, loading state)
   - Error states
3. Use Vitest and React Testing Library
4. Follow our testing conventions in src/__tests__/

Why It Works

Assigning a role helps the AI adopt the right mindset and follow appropriate patterns.


Technique 6: Reference Specific Files

Bad Prompt

Add form validation

Good Prompt

Look at src/components/LoginForm.tsx and add form validation:
- Validate email format
- Validate password (min 8 chars)
- Show inline error messages below each field
- Disable submit button while validation fails
- Use the existing error message component from src/components/ErrorMessage.tsx

Why It Works

Direct file references give the AI exact context, reducing hallucinations.


Technique 7: Chain of Thought

Bad Prompt

Fix this bug in the payment processing

Good Prompt

The payment is being charged twice when the user clicks the submit button rapidly. Trace through the code flow:

1. First, explain how the payment flow currently works
2. Identify where the double-charge happens
3. Implement a fix that:
   - Disables the button during processing
   - Uses idempotency keys to prevent duplicate charges
   - Shows appropriate loading states

Explain your reasoning at each step

Why It Works

Asking for explanation ensures the AI thinks through the problem and produces better solutions.


Technique 8: Use Constraints to Guide

Bad Prompt

Refactor this file

Good Prompt

Refactor this file to improve readability. Constraints:
- Keep all existing functionality
- Maximum function length: 20 lines
- Extract repeated code into utilities
- Add JSDoc comments to exported functions
- Use early returns for error cases
- Keep the same performance characteristics

Why It Works

Clear constraints give the AI a framework to work within.


Real-World Prompt Examples

Code Generation

Generate a TypeScript interface for a GitHub repository:
- id (number)
- name (string)
- full_name (string - "owner/repo")
- description (string | null)
- owner (object with login and avatar_url)
- stargazers_count (number)
- forks_count (number)
- language (string | null)
- created_at (Date)
- updated_at (Date)

Bug Fixing

Fix the memory leak in this React component. The issue is that the event listener added in useEffect is never cleaned up. Show me:
1. The problem in the current code
2. The corrected code
3. How the cleanup function should work

Code Review

Review this PR for:
- Security vulnerabilities
- Performance issues
- Code smells
- Missing edge cases
- Inconsistents with our coding standards

Focus on the files in src/api/

Refactoring

Convert this class component to a functional component with hooks. Maintain:
- All existing functionality
- Prop types
- Default props
- Same render output

Then explain what changed and why each change was made.

Common Mistakes to Avoid

1. Being Too Vague

"Make this better"

"Refactor to use async/await instead of callbacks"

2. Missing Context

"Add authentication"

"Add JWT-based authentication using our existing user table"

3. Too Many Changes at Once

"Rewrite the entire app with new UI and add login"

✅ (Break into multiple prompts)

4. Not Reviewing Output

Always review AI-generated code before accepting. Check for:

  • Security issues
  • Logic errors
  • Performance problems
  • Missing edge cases

Key Insight: The best prompts are specific, structured, and iterative. Don’t try to get everything in one go — build up your application piece by piece.


Practice Exercise

Take one of your existing projects and try to:

  1. Generate a component using a vague prompt — note the issues
  2. Regenerate with a detailed, structured prompt — compare results
  3. Iterate with follow-up prompts — see how much better the result gets

You’ll be surprised at the difference good prompting makes!


Summary

Good prompt engineering is a skill that improves with practice. Remember:

  1. Provide context — Tell the AI about your project
  2. Show examples — Reference existing patterns
  3. Break it down — Tackle complex tasks incrementally
  4. Be specific — Clear prompts yield better results
  5. Iterate — Build up gradually, refine often

The time you invest in writing better prompts will pay dividends in code quality and development speed.