10 ChatGPT Prompts Every Developer Should Know (With Real Examples)
Most developers use ChatGPT the same way they Google things: dump in a vague question and hope for something useful. Sometimes it works. Usually it doesn't.
The difference between a useless ChatGPT response and a genuinely helpful one comes down to the prompt. Vague prompts get vague answers. Specific prompts with context get specific, actionable output.
Here are 10 prompts I use regularly — each one shown as a weak version (what most people write) and a strong version (what actually works). I've included real code examples throughout.
1. Explaining Unfamiliar Code
Weak prompt:
What does this code do?
def process(items, threshold=0.5):
return [x for x in items if x.score > threshold and not x.archived]
Strong prompt:
Explain this Python function to me as if I'm familiar with Python but haven't
seen this codebase before. Tell me: what it does, what the parameters mean,
what it returns, and one potential edge case I should watch for.
def process(items, threshold=0.5):
return [x for x in items if x.score > threshold and not x.archived]
Why it works: The first prompt gets a one-liner description. The second gets a structured explanation with edge cases you'd actually care about — like what happens when items is empty, or when every item is archived.
Sample output from the strong prompt:
-
items: a list of objects, each expected to have.score(float) and.archived(bool) attributes -
threshold: the minimum score for an item to pass through (default: 0.5) - Returns a filtered list — items where score is above threshold AND not archived
- Edge case: if any item in
itemsdoesn't have.scoreor.archived, this raisesAttributeErrorwith no helpful message
That last point is something you'd want to know before this hits production.
2. Code Review With Specific Criteria
Weak prompt:
Review my code.
async function fetchUserData(userId) {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
return data;
}
Strong prompt:
Review this JavaScript function against these specific criteria:
1. Error handling: does it handle network failures or non-200 responses?
2. Security: any injection or exposure risks?
3. Type safety: what assumptions does it make that could break at runtime?
4. One thing I should change first if I only have time for one fix.
async function fetchUserData(userId) {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
return data;
}
Why it works: "Review my code" gets generic feedback. The specific criteria version gets a prioritized list of actual problems — in this case: no error handling for 4xx/5xx responses, response.json() throws on non-JSON responses, userId isn't validated so a malformed value hits the API, and the #1 fix is wrapping in try/catch with status checking.
3. Writing Tests for Edge Cases
Weak prompt:
Write tests for this function.
function divide(a, b) {
return a / b;
}
Strong prompt:
Write Jest unit tests for this JavaScript function. Cover: the happy path,
divide by zero, non-numeric inputs, negative numbers, and floating point
precision. For each test, explain in a comment why that edge case matters.
function divide(a, b) {
return a / b;
}
Why it works: The weak version gets you expect(divide(4, 2)).toBe(2). The strong version gets you this:
describe('divide', () => {
test('divides two positive numbers', () => {
expect(divide(10, 2)).toBe(5);
});
test('returns Infinity for divide by zero (not an error)', () => {
// JavaScript returns Infinity, not throws — callers must handle this
expect(divide(5, 0)).toBe(Infinity);
});
test('returns NaN for non-numeric input', () => {
// Catches cases where upstream passes strings
expect(divide('a', 2)).toBeNaN();
});
test('handles negative divisor', () => {
expect(divide(10, -2)).toBe(-5);
});
test('floating point result', () => {
// Use toBeCloseTo, not toBe, for floats
expect(divide(1, 3)).toBeCloseTo(0.333, 3);
});
});
The comment on toBeCloseTo alone is worth the prompt upgrade.
4. Debugging — Cause-First Approach
Weak prompt:
My app is crashing. What's wrong?
TypeError: Cannot read properties of undefined (reading 'map')
Strong prompt:
I'm getting this error in a React component. The component receives a `users`
prop from a parent that fetches data from an API. Help me identify the root
cause (not just the symptom) and the correct fix. Also tell me how to prevent
this class of error in the future.
Error: TypeError: Cannot read properties of undefined (reading 'map')
Stack: at UserList (UserList.jsx:12)
Relevant code:
function UserList({ users }) {
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Why it works: The weak version gets "check if users is defined." The strong version gets a proper root cause analysis:
- Root cause:
usersisundefinedduring the render before the API call completes - Not a bug in
UserList— it's a contract violation from the parent - Fix options ranked by correctness: (1) default prop
users = [], (2) conditional render in parent, (3) early return in component - Prevention: use TypeScript
users: User[]to catch this at compile time
5. Architecture Review With Constraints
Weak prompt:
Is this a good architecture?
User → API Gateway → Lambda → DynamoDB
Strong prompt:
Review this architecture for a read-heavy SaaS dashboard serving 50k daily
active users. Our constraints: <$500/month infra budget, team of 3 engineers,
no dedicated DevOps. Identify the biggest risk with this setup and one concrete
alternative.
Architecture: User → API Gateway → Lambda → DynamoDB
Why it works: Without constraints, you get "it depends." With constraints, you get specific tradeoffs: DynamoDB read costs at scale, Lambda cold starts hurting dashboard load times, no caching layer being the biggest risk, and a concrete alternative: add CloudFront + DynamoDB DAX for hot reads, or switch to Postgres on Railway under that budget constraint.
6. Writing Documentation
Weak prompt:
Write docs for this function.
def send_email(to, subject, body, cc=None, attachments=None):
...
Strong prompt:
Write a docstring for this Python function in Google style. Include:
a one-line summary, Args with types and descriptions, Returns, Raises,
and one usage example showing the most common case.
def send_email(to, subject, body, cc=None, attachments=None):
...
Why it works:
def send_email(to, subject, body, cc=None, attachments=None):
"""Send an email via the configured SMTP provider.
Args:
to (str | list[str]): Recipient address or list of addresses.
subject (str): Email subject line.
body (str): Plain-text or HTML email body.
cc (list[str], optional): CC recipients. Defaults to None.
attachments (list[Path], optional): File paths to attach. Defaults to None.
Returns:
str: Message ID assigned by the SMTP server.
Raises:
SMTPAuthError: If SMTP credentials are invalid.
FileNotFoundError: If any attachment path does not exist.
Example:
msg_id = send_email(
to="user@example.com",
subject="Your report is ready",
body="See attached PDF.",
attachments=[Path("report.pdf")]
)
"""
The Raises section is the part most developers skip and then regret.
7. Refactoring With Constraints
Weak prompt:
Refactor this code.
for i in range(len(orders)):
if orders[i]['status'] == 'pending':
if orders[i]['amount'] > 1000:
orders[i]['priority'] = 'high'
else:
orders[i]['priority'] = 'normal'
Strong prompt:
Refactor this Python code with these constraints: (1) don't change external
behavior, (2) keep it readable for a junior developer, (3) no new dependencies.
Show the before/after and explain each change you made and why.
[paste code]
Why it works: You get a proper refactor with explanation, not just a rewrite:
for order in orders:
if order['status'] == 'pending':
order['priority'] = 'high' if order['amount'] > 1000 else 'normal'
Changes:
-
range(len(...))→ direct iteration: Python idiom, less error-prone - Nested if/else → ternary: same logic, one line — readable because the condition is simple
-
orders[i]→order: clearer variable name
Constraint (3) ruled out using something like pandas which some refactors might reach for.
8. SQL Query Optimization
Weak prompt:
Make this SQL faster.
SELECT * FROM orders WHERE status = 'pending' ORDER BY created_at DESC;
Strong prompt:
This PostgreSQL query runs on a table with 2M rows. It's taking 800ms on average.
Identify why it's slow and suggest optimizations in order of impact. Include the
exact CREATE INDEX statement I'd run.
SELECT * FROM orders WHERE status = 'pending' ORDER BY created_at DESC LIMIT 50;
Table schema:
- id (uuid, primary key)
- status (varchar, values: pending/completed/cancelled)
- created_at (timestamp)
- customer_id (uuid)
- amount (decimal)
Why it works: You get a root cause (full table scan on status, sort on unindexed column) plus ranked fixes:
-
Highest impact:
CREATE INDEX idx_orders_status_created ON orders(status, created_at DESC) WHERE status = 'pending';— partial index only covers pending rows, covering index eliminates table lookup -
Medium: Replace
SELECT *with explicit columns to reduce I/O - Low: Partition by status if the table grows beyond 50M rows
The partial index tip alone can cut that 800ms to under 10ms.
9. API Design Critique
Weak prompt:
Is this API good?
POST /api/updateUser
Strong prompt:
Critique this REST API design for a user management service. Flag any violations
of REST conventions, security concerns, and usability issues. For each problem,
give the corrected version.
Endpoints:
POST /api/updateUser
GET /api/getUser?id=123&include_password=true
DELETE /api/users/deleteAll
POST /api/users/search
Why it works: You get a specific critique:
| Problem | Fix |
|---|---|
Verb in URL (updateUser) |
PATCH /api/users/{id} |
include_password=true exposes sensitive data |
Never return password fields; use /api/users/{id}/credentials with scoped auth |
deleteAll with no safeguard |
Require explicit body {"confirm": true} or use a separate admin-scoped endpoint |
POST /search instead of GET
|
GET /api/users?q=... for simple search; POST only if search params are sensitive |
10. Stack Selection With Tradeoffs
Weak prompt:
What's the best stack for a web app?
Strong prompt:
I'm building a B2B SaaS app: multi-tenant, dashboard-heavy, ~10k users at launch.
My team knows Python well but no TypeScript. We need to ship an MVP in 6 weeks.
Give me 2 stack options with honest tradeoffs for our situation. Don't recommend
what's popular — recommend what fits these constraints.
Why it works: Instead of "React + Node is popular," you get:
Option 1: FastAPI + HTMX + PostgreSQL
- Fits Python expertise, no TS context switch
- HTMX handles dashboard interactivity without a full SPA
- Risk: less frontend flexibility if you later need complex client-side state
Option 2: Django + React + PostgreSQL
- Django admin saves weeks on internal tooling
- React is the right call if the dashboard needs complex interactivity
- Risk: React adds 2–3 weeks of onboarding if the team is new to it
For a 6-week MVP with a Python team: Option 1. Ship faster, add React later if you need it.
The Pattern Behind All 10
Every strong prompt shares the same structure:
- Context — what you're working with, what constraints exist
- Specific ask — not "review" but "review against these 4 criteria"
- Format request — "show me before/after," "rank by impact," "explain each change"
That's it. The more specific your input, the more useful the output.
If these 10 prompts saved you time, I have 200+ more developer prompts organized by category — code review, debugging, architecture, testing, documentation, and more.
Get the full ChatGPT Prompts for Developers pack →
It's $19 and covers every workflow I've found prompts actually useful for.
Top comments (0)