10 ChatGPT Prompts Every Software Developer Should Know
I walk through 10 tested prompt templates for debugging, code review, testing, and documentation, and explain the structure behind why each one actually works.

A vague prompt gets a vague answer. That sounds obvious, but most developers learn it by spending twenty minutes with a wall of “here are several possible reasons” instead of the one-line fix they needed.
The issue isn’t the model — it’s the prompt shape. When you give a language model a role, show it the real context, name the specific problem, and ask for a concrete output format, the response quality changes noticeably. That structure applies to debugging, code review, testing, documentation, and most other things developers do throughout the week.
The 10 templates below follow that structure. Each one has been shaped to avoid the most common failure modes for that particular task.
Quick answer: All 10 templates share the same pattern: give the model a role, show the relevant code or context, state the actual problem or goal, and ask for a specific output. Copy a template, replace the bracketed sections with your real code, and adjust the focus areas to match what you need.
On this page
- Debugging and error analysis
- Code review and refactoring
- Testing and documentation
- Architecture, SQL, and planning
- Regex and git commit messages
- Where these prompts fall apart
- The prompt is the spec — write it the same way
Debugging and error analysis
Debugging is where most developers first reach for an AI assistant, and it’s also where prompt quality matters most. The model needs specific information to give a specific answer.
Prompt 1: Explain the error
Use this when you have an error message and the code that produced it.
You are a [language] developer. I'm getting this error:
[paste error message]
Here is the code that causes it:
[paste code]
Explain what's causing the error, name the specific line responsible,
and describe what I need to change to fix it.
The role instruction tells the model which language context to apply. Without “name the specific line,” the response tends to enumerate possible causes rather than point at the actual one. Asking for what to change keeps the answer actionable.
Prompt 2: Walk through a stack trace
Use this when you have a stack trace and need to understand what was executing when it crashed.
Walk through this stack trace from the bottom up. For each frame, name
which part of the code was running and what it was trying to do when
the error occurred. Mark the frame where the actual bug is most likely sitting.
[paste stack trace]
Reading from the bottom up reflects execution order — the bottom is where the call started, the top is where it died. Asking the model to mark the likely culprit forces a decision instead of a list. If you ask it to “explain the stack trace” without direction, you get a description of every frame, which is the part you could have read yourself.
Try this
Take the last error message you’ve seen this week. Paste it into the first template above, including the code that triggered it.
Expected result: You should get a response pointing to a specific line and explaining the reason, rather than a set of general suggestions.
Code review and refactoring
These are two distinct tasks and they need different prompt shapes. A review should find real problems. A refactor should meet specific goals without changing the interface.
Prompt 3: Targeted code review
Review this [language] code. Focus on:
- Edge cases that aren't handled
- Inputs that could cause unexpected behavior
- Security issues if this code processes user input
Do not suggest stylistic rewrites. Flag real problems only.
[paste code]
Without explicit focus areas, code reviews drift toward style preferences. “Do not suggest stylistic rewrites” is the line that keeps the response on problems that matter. You can adjust the focus list — for example, replace the security point with “performance on large inputs” if that’s more relevant to your function.
Prompt 4: Refactoring with constraints
Refactor this [language] function to:
- [specific goal, e.g., eliminate the duplicate condition checks]
- [specific goal, e.g., handle the null case explicitly]
Keep the function signature identical. Show the refactored function only.
[paste function]
“Keep the function signature identical” is the constraint developers forget until they have broken call sites to fix afterward. Without explicit goals, “refactor this” produces whatever the model thinks is cleaner — which may not align with what you actually need. The shorter the goal list, the more focused the result.
Testing and documentation
Tests and docs have the same failure mode in prompt form: you ask for them generically, you get the obvious cases back, and the useful detail is missing.
Prompt 5: Generate tests with categories
Write unit tests for this [language] function using [testing framework]. Cover:
- The normal path with typical valid input
- Edge cases: empty input, null, zero, and boundary values if numeric
- Error cases: inputs that should throw or return an error value
[paste function]
Without the category list, the model writes three or four tests that check the same happy path. Listing the categories explicitly acts as a test plan. You’ll still need to add tests for business logic edge cases the model can’t know — cases that depend on what the code is supposed to mean, not just what it does. I’ve found the scaffolding from this prompt accurate enough to build on.
Check this before moving on
- Your prompt includes the actual function code, not just a description of it
- You’ve named the testing framework so the generated syntax is correct
- You’ve reviewed the generated edge cases — the model can’t produce business-logic edge cases it doesn’t know about
Prompt 6: Write JSDoc comments
Write a JSDoc comment for this TypeScript function. Include:
- @param with type and a one-sentence description for each argument
- @returns with type and what the value represents
- @throws if the function can throw
- One @example showing a realistic call and its return value
[paste function]
Specifying the exact tags you want avoids the model guessing your documentation style. The @example tag is the one developers consistently forget to ask for, and it’s the one that makes IDE tooltips genuinely useful in practice.
Architecture, SQL, and planning
Both of these prompts are planning tasks. The key for planning is that constraints drive useful output. Without constraints, you get advice that’s technically sound but too general to act on.
Prompt 7: Architecture brainstorming
I'm building [brief description]. My constraints are:
- [constraint 1, e.g., must run without a separate background job queue]
- [constraint 2, e.g., expected load: a few hundred requests per day]
- [constraint 3, e.g., existing stack: Node.js and PostgreSQL]
Suggest two or three different approaches. For each, describe the
trade-offs and name a situation where that approach would be the wrong choice.
Asking for “a situation where this would be the wrong choice” is the most useful part. It forces the model to give you the information you’d need to rule out an approach, not just reasons to choose it. Without that, every suggestion sounds equally valid.
Prompt 8: SQL query optimization
This query is running slowly. Here is the query:
[paste SQL]
Here is the EXPLAIN output:
[paste EXPLAIN or EXPLAIN ANALYZE output]
Suggest specific optimizations. For each suggestion, explain why it
would help and what to watch out for.
Without the EXPLAIN output, all SQL optimization advice defaults to “consider adding an index.” With it, the model can reason about what the query planner is actually doing — join order, sequential scans, hash joins — and give you a suggestion grounded in your specific plan rather than a generic recommendation.
Regex and git commit messages
Two tasks that seem simple but produce frustrating output when the prompt is too sparse.
Prompt 9: Generate regex with examples
Write a regular expression that matches [describe the pattern].
Strings that must match:
[list 3-5 examples]
Strings that must not match:
[list 3-5 examples]
Explain each part of the regex. Then provide a test snippet in [language]
that runs against both lists.
Regex without examples is a guessing game on both sides. Giving both match and no-match examples surfaces the edge cases that a description alone misses — the “almost right” pattern that passes your examples but fails on input you didn’t think to include. The test snippet makes it easy to verify the regex actually does what you said you needed.
Prompt 10: Git commit message
Write a git commit message for this change. Use Conventional Commits
format: <type>(<scope>): <summary> under 72 characters.
If the change is complex, add a body paragraph explaining why this
change was made — not what was changed, the diff shows that.
[paste git diff or describe what changed]
“Not what was changed, the diff shows that” is the most useful instruction in this template. The commit message that restates the diff isn’t useful six months later. The one that explains why the change was made is.
Where these prompts fall apart
Missing project context. The model doesn’t know your type definitions, naming conventions, or domain rules unless you include them. A test generation prompt that works well on a standalone pure function produces rough scaffolding for a complex service — you’ll supply the cases that require understanding what the code should mean, not just what it currently does.
Minified or obfuscated stack traces. Stack traces from production bundles are often stripped to the point where frame names are meaningless. The model can identify the error type and describe the top-level wrapper, but it can’t reason through mangled variable names.
Architecture advice without team context. The model suggests technically sound approaches without knowing your team’s experience level or what infrastructure you’ve already built. An approach that’s clean on paper might require knowledge your team doesn’t currently have or duplicate something you’ve already implemented.
SQL optimization without data distribution. Index recommendations from an EXPLAIN output are often correct, but the model can’t see your actual data distribution. An index that looks helpful on a small table might behave differently once the table grows or once the query pattern changes.
All of these are prompting limits, not model limits. The fix is to add more context — paste in the type definitions, describe the team constraint, mention the table size. The templates are starting points, not maximally informative prompts.
The prompt is the spec — write it the same way
Every prompt that works well answers three questions: what are you working with, what do you expect, and what do you actually need. Those are the same three questions a good bug report answers, and the same ones a clear code comment answers.
The templates above apply that structure to the tasks developers do most often. They’ll need adjustment for your specific language and context — the brackets are a reminder to fill in real information, not a place to leave placeholder text.
If you’re building a test suite for a JavaScript or TypeScript project and want to understand what good test coverage actually looks like in practice, my post on testing JavaScript applications covers the patterns these prompts should be generating. For TypeScript specifically, the TypeScript for JavaScript developers post explains the type system details that matter most when you’re writing JSDoc and refactoring prompts.