The quality of AI output depends almost entirely on the quality of your prompt. This lesson teaches you how to write prompts that get useful, precise, production-ready code.
A strong code prompt has five elements:
| Element | Purpose | Example |
|---|---|---|
| Role | Tell AI who it is | "You are a senior Laravel developer." |
| Context | What codebase / situation | "This is a Laravel 11 API with Sanctum auth." |
| Task | What to produce | "Write a controller method to update user profile." |
| Format | How to output it | "Return only the PHP method, no explanation." |
| Constraints | Rules to follow | "Use Form Requests. No raw SQL." |
| Bad prompt | Good prompt |
|---|---|
| "Make a login page" | "Write a Vue 3 login form with email + password, Pinia auth store integration, and inline error messages on failed login. Use Tailwind CSS." |
| "Fix my code" | "This function throws 'Cannot read property of undefined' on line 12. Here's the function: [code]. Input is an array of user objects. What's the bug and fix?" |
| "Write tests" | "Write Vitest unit tests for calculateDiscount(price, percent). Cover: normal case, 0%, 100%, negative price, non-number inputs." |
| "Refactor this" | "Refactor for readability. Do not change behavior or function signature. Add JSDoc comments." |
| "Help with SQL" | "Write a PostgreSQL query for the top 10 customers by order value in the last 30 days. Tables: orders(id, customer_id, total, created_at), customers(id, name, email)." |
For code generation, be specific about: language/framework, function signature, inputs/outputs, edge cases, and what to avoid.
# Template: "Write a [language] [function/class/component/endpoint] called [name] that [does X]. Input: [params and types] Output: [return value description] Requirements: - [requirement 1] - [requirement 2] Edge cases to handle: - [edge case 1] Do NOT: [thing to avoid]" # Example: "Write a JavaScript function called formatCurrency(amount, currency) that formats a number as a currency string. Input: amount (number), currency (string, e.g. 'USD', 'EUR') Output: formatted string like '$1,234.56' Requirements: - Use the Intl.NumberFormat API - Default currency to 'USD' if not provided Edge cases: amount is 0, negative, NaN or undefined (return 'N/A') Do NOT use any external libraries."
# Structure: "I'm getting this error: [paste exact error + stack trace] Here is the relevant code: [paste the function or component] Context: - Framework: [Laravel 11 / Vue 3 / Node 20] - This happens when: [describe the trigger] - Expected: [what should happen] - Actual: [what does happen] What is causing this and how do I fix it?"
# Key rules for refactoring prompts: # Explicitly say "do not change behavior" "Refactor the following function: [paste code] Goals: - Improve readability (shorter lines, clearer names) - Extract repeated logic into helper functions - Add JSDoc comments for the main function Constraints: - Do NOT change the function signature - Do NOT change the return type or shape - Keep all existing edge case handling"
Build features step by step. This produces better results and keeps you in review of each piece.
# Instead of: "Build me a full e-commerce cart system"
# Step by step:
Step 1: "Write a Pinia store for a shopping cart with:
- state: items [{id, name, price, qty}]
- getters: totalItems, totalPrice
- actions: addItem, removeItem, updateQty, clearCart"
Step 2: "Write a Vue 3 CartItem component that receives a cart
item as a prop and emits 'remove' and 'change-qty'."
Step 3: "Write a CartSummary component using the Pinia store
showing subtotal, 8% tax, and total."
Step 4: "Add a checkout() action to the store that POSTs to
/api/checkout and clears the cart on success."
| Type | Purpose | Where to put it |
|---|---|---|
| System prompt | Persistent persona, project rules, conventions | CLAUDE.md, .cursorrules, API system field |
| User prompt | The specific task for this interaction | Each message / request |
# Example system prompt content (CLAUDE.md or .cursorrules): You are an expert in Vue 3, Laravel 11, and Tailwind CSS. This project uses: - Vue 3 Composition API with TypeScript - Pinia for state management - Laravel Sanctum for auth - Tailwind CSS (no custom CSS unless asked) Always: - Use async/await (not .then()) - Add TypeScript types to all function params and returns - Follow naming: PascalCase components, camelCase composables Never: - Use the Options API - Add console.log to production code - Use jQuery
"Write a Vue 3 [ComponentName] using Composition API + TypeScript. Props: [list with types]. Emits: [list events]. Behavior: [describe]. Use Tailwind CSS."
"Write a Laravel 11 controller method [name] for [METHOD /path]. Request: [input fields]. Response: [JSON shape]. Validation: [rules]. Use a Form Request class."
"Write Vitest tests for the function below. [paste function] Cover these cases: [list]. Mock any external dependencies."
"Write a Laravel migration to create [table_name] with: [col]: [type, nullable/required, default] Indexes on: [cols]. Foreign keys: [relationships]."
"Review the following code for security vulnerabilities:
[paste code]
Check for: SQL injection, XSS, IDOR, missing auth checks,
sensitive data exposure, input validation gaps."