Prompt Engineering for Code
How you phrase a prompt directly affects the quality of the output. This page covers practical techniques for code-related tasks, plus the workspace instruction files that let you front-load context once for the whole repo.
Principles of Effective Promptsโ
- Be specific and concrete. Include the language, framework, relevant types/interfaces, and surrounding context โ not just "write me a function."
- State constraints explicitly. "Don't change the public API" or "keep the existing test structure" are things the AI won't infer on its own.
- Specify the output format. Do you want code only, code with explanation, code with tests, or a refactored diff? Say so.
- Use few-shot examples. Paste a snippet of your codebase's style and the model will match it far better than it would from style descriptions alone.
- Ask for reasoning on complex tasks. "Explain your approach before writing the code" produces more careful output and lets you catch a wrong direction early.
Prompt Patterns for Common Tasksโ
Generating New Codeโ
Include: the language and framework, any relevant types or interfaces, what module or file this belongs in, and what you've already got. The richer the context, the less the model invents.
Example prompt structure:
I'm working in a React 18 + TypeScript project using React Query and Zod.
I need a custom hook called `useUserProfile` that:
- Fetches `/api/users/:id` using React Query
- Validates the response with this Zod schema: [paste schema]
- Returns `{ data, isLoading, error }` โ typed strictly, no `any`
Don't add error boundary logic; we handle that at the page level.
Here's how another similar hook looks in this codebase: [paste example]
Refactoringโ
- Include the full function or module to be changed.
- State what to change and what to leave alone.
- Specify invariants: "preserve the return type," "don't add new dependencies," "keep the existing tests passing."
Debuggingโ
- Include the full error message and stack trace.
- Paste the relevant code.
- Describe what you've already tried.
- Ask for step-by-step reasoning before the fix: this catches cases where the model would jump to the wrong conclusion.
Code Review and Explanationโ
- Ask for specific feedback dimensions: correctness, performance, security, readability.
- "What edge cases is this missing?" is a more productive prompt than "review this."
- "Explain this code as if I'm new to this codebase" works better than "what does this do?"
Workspace Instruction Filesโ
These files give the AI persistent context about your project without pasting it into every prompt. Set them up once per repo, and every prompt benefits.
GitHub Copilot โ .github/copilot-instructions.mdโ
Copilot reads this file and incorporates it as system-level context for all Copilot Chat interactions in the workspace.
What to include: tech stack and versions, coding conventions, folder structure, preferred patterns, patterns to avoid.
# Copilot Instructions
## Stack
- React 18, TypeScript 5, Vite
- React Query for data fetching, Zod for validation
- Tailwind CSS + shadcn/ui for styling
## Conventions
- All components use named exports (no default exports)
- Use React Query for all server state; avoid `useState` for async data
- Validate all API responses with Zod schemas before use
- Prefer `const` arrow functions for components
## Do Not
- Add `any` types โ use `unknown` and narrow instead
- Install new dependencies without discussing in a PR
- Use `useEffect` for data fetching โ use React Query instead
Reference: GitHub Copilot custom instructions
Cursor โ .cursorrulesโ
Cursor reads .cursorrules at the repo root as a standing system prompt for all Cursor Chat and Composer interactions.
You are an expert TypeScript and React developer.
This project uses React 18, TypeScript 5, React Query, Zod, Tailwind CSS, and shadcn/ui.
Always:
- Use named exports for components
- Type everything strictly โ no `any`
- Use React Query for server state
- Validate API responses with Zod
Never:
- Add new npm packages without noting it
- Use useEffect for data fetching
- Generate default exports for components
Cursor is also moving toward a .cursor/rules/ folder for modular, file-glob-scoped rules. See the Cursor documentation for the latest on this.
Claude Code โ CLAUDE.mdโ
Claude Code reads CLAUDE.md at the project root when starting a session. It's the most important context file for agentic Claude workflows.
Recommended content: project description, tech stack, key architecture decisions, how to run the dev server and tests, common commands.
# Project: My App
A React + Node.js web application for [brief description].
## Stack
- Frontend: React 18, TypeScript 5, Vite, React Query, Tailwind CSS, shadcn/ui
- Backend: Node.js 20, Express, Prisma, PostgreSQL
- Testing: Vitest (unit), Playwright (E2E)
## Running the project
- `npm run dev` โ start the dev server (frontend on :5173, backend on :3000)
- `npm test` โ run unit tests
- `npm run test:e2e` โ run Playwright tests
## Key conventions
- Named exports everywhere
- All API responses validated with Zod
- No `any` types
- Feature folders: `src/features/<name>/{components,hooks,api,types}.ts`
Reference: Claude Code memory docs
AGENTS.md โ Tool-Agnostic Conventionโ
AGENTS.md is a tool-agnostic convention for providing instructions to AI coding agents. Instead of maintaining separate files for each tool, you write one AGENTS.md that supporting agents can read โ though not all tools support it yet (unsupported tools will simply ignore the file).
Place AGENTS.md at the repo root for global instructions. Additional AGENTS.md files in subdirectories scope instructions to that directory โ similar to how .gitignore works hierarchically.
The content is essentially the same as what you'd put in CLAUDE.md: project overview, tech stack, commands, conventions, and constraints.
# Project: My App
## Overview
A React + Node.js web application for [brief description].
## Stack
- Frontend: React 18, TypeScript 5, Vite, React Query, Tailwind CSS
- Backend: Node.js 20, Express, Prisma, PostgreSQL
- Testing: Vitest (unit), Playwright (E2E)
## Commands
- `npm run dev` โ start dev server
- `npm test` โ run unit tests
- `npm run lint` โ lint and type-check
## Conventions
- Named exports for all components (no default exports)
- Validate all API responses with Zod schemas
- No `any` types โ use `unknown` and narrow
- Feature folders: `src/features/<name>/{components,hooks,api,types}.ts`
## Do Not
- Add new dependencies without discussing in a PR
- Use `useEffect` for data fetching โ use React Query
- Commit generated files or build artifacts
| Tool | Reads AGENTS.md? | Notes |
|---|---|---|
| Claude Code | โ | Reads alongside CLAUDE.md |
| OpenAI Codex | โ | Primary instruction file |
| GitHub Copilot | โ | Uses .github/copilot-instructions.md |
| Cursor | โ | Uses .cursorrules / .cursor/rules/ |
When to use AGENTS.md:
- Multi-tool teams โ use
AGENTS.mdas a single source of truth that all supported agents read. - Single-tool teams โ a vendor-specific file (
CLAUDE.md,.cursorrules) may be simpler. - Hybrid โ use
AGENTS.mdfor shared conventions, plus vendor-specific files for tool-unique features.
Reference: AGENTS.md convention
For a tool-agnostic convention with varying tool support, see AGENTS.md above. Copilot also supports scoped instruction files (*.instructions.md) and reusable prompt templates (*.prompt.md) for more granular control. See Copilot Customization Files for full details.
VS Code Copilot Techniquesโ
@workspaceโ semantic search across all open workspace files. Use it to ask questions about your codebase:@workspace how is authentication handled?@terminalโ include terminal output (errors, build failures) as context for a fix.#file/#selectionโ explicitly scope context to a specific file or highlighted code block.#problemsโ include current diagnostics (errors and warnings) from the Problems panel as context.#fetchโ fetch a URL and include the response content as context. Useful for referencing live documentation or API specs.- Slash commands:
/explainโ explain a piece of code in plain language/fixโ fix a bug or error in selected code/testsโ generate unit tests for selected code/docโ generate a documentation comment for selected code
@workspace /explain on an unfamiliar module is one of the highest-value quick wins when onboarding to a new codebase.
Model Selectionโ
Copilot Chat supports multiple language models. Click the model name in the chat panel header to switch โ different models suit different tasks.
| Model | Best for |
|---|---|
| GPT-4.1 | Fast general-purpose coding, good default |
| Claude Sonnet 4 | Long reasoning chains, architectural decisions, large refactors |
| o4-mini | Complex logic where step-by-step reasoning helps, math-heavy code |
| Gemini 2.5 Pro | Large context windows, analyzing many files at once |
Model availability depends on your Copilot subscription tier. The model picker shows only models available to you.
Model selection affects chat and agent mode only โ inline completions (ghost text) use a separate, fast model that isn't user-configurable.
Vision & Image Contextโ
Copilot Chat accepts image attachments when using a vision-capable model (GPT-4o, Claude Sonnet, Gemini). Drag and drop or paste an image directly into the chat input.
Use cases:
- UI mockup โ code โ paste a wireframe or Figma screenshot and ask Copilot to implement it
- Bug reproduction โ attach a screenshot of broken UI with the question "why does this render wrong?"
- Diagram interpretation โ paste an architecture diagram and ask Copilot to scaffold the described structure
Combine image context with #file references for best results: paste a mockup and reference your design system components so Copilot uses your existing component library rather than inventing new markup.
Next Edit Suggestions (NES)โ
Next Edit Suggestions predict your next logical edit after you make a change โ not just completions at the cursor, but related changes elsewhere in the file. A ghost-text suggestion appears at the predicted location; press Tab to accept.
Example: rename a parameter in a function signature โ NES suggests updating all usages of that parameter in the function body.
Enable or disable via:
{
"github.copilot.nextEditSuggestions.enabled": true
}
NES is different from inline completions. Inline completions suggest code at your cursor position. NES suggests edits at other locations in the file based on the edit you just made.
Customizing Copilot Outputsโ
Several Copilot outputs โ commit messages, generated tests, and code reviews โ can be customized with instruction settings in your VS Code settings.json (or your workspace's .vscode/settings.json). Each setting controls a different output type.
Commit Messagesโ
Copilot can generate commit messages for you โ click the sparkle icon in the Source Control panel and it drafts a message from your staged changes. Control the format and style with commitMessageGeneration.instructions:
{
"github.copilot.chat.commitMessageGeneration.instructions": [
{
"text": "Generate commit messages following this format:\n\nSubject line: `YOURPROJECT-xxxx <gitmoji> Short meaningful description`\n- Start with the Jira issue number in YOURPROJECT-xxxx format (infer from branch name if possible)\n- Follow with a relevant gitmoji (e.g. โจ new feature, ๐ bugfix, โป๏ธ refactor, ๐จ style, ๐ง config, โ
tests, ๐ docs, ๐ฅ removal, โฌ๏ธ dependency upgrade, ๐ performance)\n- Keep the subject under 72 characters, imperative mood (Add, Fix, Update)\n\nBody (optional, keep brief):\n- Only if the change isn't obvious from the subject\n- Max 2-3 short bullet points with gitmojis\n- Focus on WHY, not WHAT"
}
]
}
The example above combines Jira issue prefixes, gitmoji, and imperative-mood subjects, but you can adapt the text value to match whatever commit convention your team uses โ Conventional Commits, plain prefixes, or anything else.
Test Generationโ
The same pattern works for test output. When you use /tests or ask Copilot to generate tests, it follows testGeneration.instructions:
{
"github.copilot.chat.testGeneration.instructions": [
{
"text": "Use Vitest (describe, it, expect). Prefer userEvent over fireEvent for React Testing Library. Follow the Arrange-Act-Assert pattern. Name test files <module>.test.ts."
}
]
}
Code Reviewโ
When you select code and use Copilot's review feature, reviewSelection.instructions controls how it analyzes and reports issues:
{
"github.copilot.chat.reviewSelection.instructions": [
{
"text": "Focus on: type safety, error handling, missing edge cases, and security. Flag any use of `any` type. Note if error boundaries or fallback states are missing."
}
]
}
All four instruction settings (codeGeneration, testGeneration, reviewSelection, commitMessageGeneration) accept the same format: an array of { "text": "..." } or { "file": "path/to/file.md" } objects. The file variant lets you point to a Markdown file in the repo โ useful when the instructions are long or shared across developers.
For the full list of Copilot customization options, see the VS Code Copilot customization docs.
The text value must be a single JSON string, so use \n for line breaks. Compose the instructions in a plain text editor first, then convert to a single line with escaped newlines.
Cursor-Specific Techniquesโ
@codebaseโ full semantic search across the entire indexed repo; more powerful than@workspacefor large codebases.- Composer โ multi-file editing mode. Describe a cross-cutting change and Cursor drafts diffs across all affected files simultaneously.
.cursorrulesโ see Workspace Instruction Files above.
Resourcesโ
- VS Code Copilot documentation โ official reference for all Copilot features
- GitHub Copilot Chat prompting tips โ official prompting guidance
- Cursor documentation โ official Cursor feature reference
- Anthropic Prompt Engineering Guide โ model-agnostic prompting principles
- Burke Holland's YouTube channel โ Burke is a Senior Developer Advocate at Microsoft for VS Code and Copilot; browse his channel for practical prompting and Copilot technique videos
- VS Code YouTube channel โ search "Copilot" for feature deep dives and demos
- VS Code Copilot Customization โ the official multi-page guide to all Copilot customization options in VS Code
- awesome-copilot โ Instructions โ a curated library of real-world
.instructions.mdfiles from the community. Browse for examples to adapt when writing your own workspace instruction files.