# Prompt templates for Cursor's agent

URL: https://developertoolkit.ai/en/cursor-ide/build/prompt-templates/
Description: Copy-paste Cursor prompt templates for features, bugs, refactors, tests and review, each with a verification step, stored as Agent Skills or project rules.

A Cursor prompt template is a tested, reusable prompt that gives the agent five things up front: the task, a canonical file to copy, the boundaries, the checks to run, and the evidence to report. The verification block matters most, because it lets test and type results judge the output instead of a line-by-line diff read.

You ask Cursor's agent for "a POST endpoint for creating orders". It skips validation, invents its own error format and ignores the route pattern your team uses. Five corrective messages later you have typed more than the endpoint would have taken to write, and you still have not checked whether it works.

This page is for **developers** who use Cursor's agent every day. **Tech leads** who want one shared library for the team should read the storage section: a template that lives in the repository is reviewed like code and improves like code.

## What this Cursor prompt library covers

- Seven copy-paste templates for the tasks you repeat most: endpoint, component, migration, bug investigation, refactor, test suite and pre-PR review.
- A five-part anatomy for writing your own, with a verification block that makes the agent prove its work.
- A decision table for where each template belongs: an Agent Skill or a project rule.
- The failure modes of template libraries and how to recover from each one.

## What goes into a Cursor prompt template that works the first time?

Every template on this page has the same five parts. When a template fails, one of them is missing. A template is [prompt engineering](/en/glossary/prompt-engineering/) you write once and reuse.

| Part | What it contains | What goes wrong without it |
| --- | --- | --- |
| **Task** | One outcome, stated as behaviour: "returns 201 with the created order" | The agent solves a neighbouring problem |
| **Anchor** | An `@` reference to the file that already does it right in your repo | The agent invents a new pattern |
| **Boundaries** | Files and behaviour it must not touch, stated as "Do NOT…" | Scope creep into unrelated modules, edited tests |
| **Verification** | The exact commands to run: tests, type check, lint | You have to verify by reading the diff |
| **Report** | The format of the final message: files changed, command output, open questions | "Done" with no evidence |

The anchor does more work than any adjective. "Follow the pattern in `@src/routes/users.ts`" carries your validation, error handling, logging and response shape in one reference. For how `@` references pull files into context, see [context management in Cursor](/en/cursor-ide/quick-start/context-management/). For the general technique behind these five parts, see [effective prompting techniques](/en/method/principles/prompting-techniques/).

## Which template should you use for which task?

Start a restructure in **Plan Mode**, which Cursor describes as creating "detailed implementation plans before writing any code", then switch to Agent. Run investigations in Agent, because they have to execute code: the bug template writes and runs a failing test, and the performance template runs a benchmark. Those prompts forbid source edits themselves and stop before the fix. The verification gate is what you check instead of the diff.

| Task | Template | Start in | The gate you check |
| --- | --- | --- | --- |
| New endpoint | New API endpoint | Agent | New tests pass, full suite green, type check clean |
| New UI component | New React component | Agent | Component tests for loading, error and success states |
| Schema change | Database migration | Agent | Migration applies and rolls back on the local database |
| Unknown bug | Bug investigation | Agent, stops before the fix | A failing test that reproduces the bug |
| Slow path | Performance investigation | Agent, stops before the fix | Before-and-after numbers from the same measurement |
| Restructure | Refactor | Plan Mode, then Agent | Unchanged test suite still green, public exports unchanged |
| Missing coverage | Test suite | Agent | Each test fails when the behaviour it covers is broken |
| Before the PR | Pre-PR review | Agent, with no edits | A findings table you triage |

## Feature templates for endpoints, components and migrations

The feature templates put the acceptance criteria first and ask for the tests before the implementation, so the tests describe the behaviour you asked for rather than the code the agent happened to write. For the full technique, see [executable acceptance criteria](/en/workflows/plan/acceptance-criteria/).

**Copy-paste prompt: new API endpoint**

```text
Add a POST /api/orders endpoint.

Acceptance criteria:
- A valid body returns 201 with the created order.
- An invalid body returns 400 in the error format from @src/lib/errors.ts.
- A request without a session returns 401 (use the withAuth middleware).

Anchor: follow @src/routes/users.ts exactly for route structure, Zod validation,
error handling and response shape. Validate with a Zod schema in src/schemas/order.ts.
Call the existing service in @src/services/order-service.ts.

Order of work:
1. Write the tests for the three criteria first in src/routes/__tests__/orders.test.ts,
   following @src/routes/__tests__/users.test.ts. Run them and confirm they fail.
2. Implement the endpoint and register it in @src/app.ts.

Do NOT modify existing endpoints, existing tests or the error helpers.

Verify: run `npx vitest run src/routes`, then `npx tsc --noEmit`, then `npm run lint`.
Report: files changed, the last 20 lines of each command's output, and any
assumption you made about the order payload.
```

**Copy-paste prompt: new React component**

```text
Create UserNotificationPreferences in src/components/UserNotificationPreferences.tsx.

Behaviour:
- Props: { userId: string; onSave: (prefs: NotificationPrefs) => void }
- Loads preferences from GET /api/users/:userId/notification-preferences.
- Shows switches for email, push, sms and weekly digest.
- Save sends PATCH to the same URL, then calls onSave with the saved value.
- Renders distinct loading, error and saved states.

Anchor: follow @src/components/UserProfile.tsx for data fetching and state handling.
Use only Button, Switch and Card from @src/components/ui/.

Do NOT create or change API endpoints; they already exist.

Verify: add src/components/__tests__/UserNotificationPreferences.test.tsx covering
the loading, error, and save paths with fetch mocked, then run
`npx vitest run src/components` and `npx tsc --noEmit`.
Report: files changed and the test output.
```

A migration template needs one extra boundary: it runs against your local database only, and it must come with a way back. drizzle-kit does not generate down migrations, so the template makes the agent write the reverse by hand and names the commands that apply it.

**Copy-paste prompt: database migration**

```text
Add an orders table with Drizzle.

Columns: id uuid primary key default gen_random_uuid(); user_id uuid not null
references users.id; status enum ('pending','confirmed','shipped','delivered',
'cancelled') default 'pending'; total_amount numeric(10,2) not null;
created_at and updated_at timestamptz default now().
Add one index on (user_id, status).

Anchor: define the table in @src/db/schema.ts in the same style as the users table,
and generate the migration with `npx drizzle-kit generate` into the existing
migrations folder.

Do NOT edit earlier migrations. Do NOT run anything against a remote or
production database; use the local DATABASE_URL from .env.local only.

Verify, with DATABASE_URL loaded from .env.local:
1. Apply the migration with `npx drizzle-kit migrate`.
2. drizzle-kit does not generate down migrations, so write the reverse by hand
   as orders_down.sql next to the generated file (DROP the index, the table and
   the enum type). Apply it with `psql "$DATABASE_URL" -f <path>/orders_down.sql`
   and show with `psql "$DATABASE_URL" -c '\d orders'` that the table is gone.
3. Apply the generated forward SQL again with `psql "$DATABASE_URL" -f <generated file>`.
Report: the generated SQL, the reverse SQL, and the output of each command.
```

## Debugging templates that reproduce before they fix

A debugging template forbids edits until the cause is proven. The proof is a failing test, not an explanation, because a plausible explanation of the wrong cause reads exactly like a correct one. For the full debugging workflow, see [bug hunting with Cursor](/en/cursor-ide/test/bug-hunting/).

**Copy-paste prompt: bug investigation**

```text
Bug: [PASTE THE ERROR AND STACK TRACE]
Trigger: [THE STEPS OR REQUEST THAT CAUSES IT]
Expected: [WHAT SHOULD HAPPEN]

Phase 1, no source edits:
- Read the stack trace and the files it names. List up to three candidate causes,
  each with the evidence for and against it.
- Write one failing test that reproduces the bug, next to the existing tests for
  that module. Run it and show that it fails for the reason you expect.

Stop after phase 1 and wait for my go-ahead.

Phase 2, after I approve:
- Make the smallest fix that turns the new test green.
- Run the whole test suite and `npx tsc --noEmit`.
Report: the root cause in two sentences, the diff summary, and both test runs.
```

Replace the three placeholders with the real error, trigger and expected result. The test from phase 1 stays in the suite as a regression guard.

**Copy-paste prompt: performance investigation**

```text
GET /api/orders?userId=... takes about 3 s; the target is under 300 ms.

No source edits yet. Measure first:
1. Run the existing benchmark in scripts/bench-orders.ts (or write one that calls
   the handler 50 times against the local database) and record the median.
2. Read the handler and everything it calls. Look for N+1 queries, sequential awaits
   that could run in parallel, over-fetching, and missing indexes.

For each finding, give the file and line, the expected effect, and the fix.
Rank them by expected effect. Stop and wait for me to pick which to apply.
After each fix I approve, rerun the same benchmark and report the new median.
```

## Refactoring and test-suite templates

A refactor is only safe when behaviour is pinned before the first move. The refactoring template therefore forbids test edits: an unchanged suite that stays green is the evidence. For larger restructures, see [refactoring strategies in Cursor](/en/cursor-ide/build/refactoring-strategies/).

**Copy-paste prompt: behaviour-preserving refactor**

```text
Split @src/services/user-service.ts into:
- src/services/user/authentication.ts (login, logout, token refresh)
- src/services/user/profile.ts (get, update, delete account)
- src/services/user/preferences.ts (notification and privacy settings)
Re-export every public function from src/services/user/index.ts.

Rules:
- Every exported name and signature stays identical.
- Update imports across the codebase to the new paths.
- Do NOT edit any test file. If a test fails, stop and tell me why.

Start this prompt in Plan Mode: list every file whose imports will change and stop.
After I approve the plan, I switch to Agent and you implement it.

Verify: `npx tsc --noEmit`, `npx vitest run`, `npm run lint`, and
`git diff --stat main -- '*.test.ts'`, which must print nothing.
Report: the output of all four commands.
```

A generated test suite has a specific weakness: tests written from the code tend to assert what the code does, including its bugs. The template makes the agent prove that each test can fail. For deeper test strategy, see [testing patterns in Cursor](/en/cursor-ide/test/testing-patterns/).

**Copy-paste prompt: test suite that can fail**

```text
Write tests for @src/services/order-service.ts in
src/services/__tests__/order-service.test.ts.

Anchor: follow @src/services/__tests__/user-service.test.ts for structure,
mocks and factory functions.

Cover: the happy path, validation errors, permission errors, database errors,
and empty and boundary inputs. Mock the database layer and the payment and email
clients. Name each test "should <behaviour> when <condition>".

Do NOT change order-service.ts.

Verify:
1. Run `npx vitest run src/services/__tests__/order-service.test.ts`; all pass.
2. For three tests of your choice, break the behaviour each one covers in
   order-service.ts, rerun, confirm that test fails, then restore the file.
Report: the test list, both runs, and `git diff --stat` showing order-service.ts
unchanged at the end.
```

## Pre-PR review template

The review template runs with no edits, and asks for a table you can triage in a few minutes. It is a first pass before human or automated review, not a replacement for either. For review in Cursor, including Bugbot on the pull request, see [code review in Cursor](/en/cursor-ide/ship/code-review/).

**Copy-paste prompt: pre-PR review**

```text
Review the changes on this branch: run `git diff main...HEAD`.
Do not edit any file.

Check, in this order:
1. Security: injection, missing auth checks, secrets in code or logs.
2. Correctness: unhandled promise rejections, error paths that swallow errors.
3. Tests: new code paths without a test; tests that were weakened or deleted.
4. Consistency with the patterns in the files each change touches.
5. Dependencies: imports of packages missing from package.json.

Output one table: severity (high, medium, low), file:line, problem, proposed fix.
List high-severity items first. If you find nothing in a category, say so.
```

## How do you check a template's output without reading every line?

You check the evidence the template forced the agent to produce, and you read code only where the evidence is weak.

1. **Read the report, not the diff.** Every template ends with a report of command output. If the output is missing or truncated, the task is not done; rerun the command yourself.
2. **Confirm the tests were not the thing that changed.** Run `git diff --stat main -- '*.test.ts'`, which covers committed and uncommitted changes against the base branch. An edited test in a task that said "Do NOT edit tests" is a red flag, whatever the reason. [Protecting the oracle](/en/workflows/test/protect-the-oracle/) shows how to make this mechanical and what Cursor can and cannot enforce.
3. **Let CI rerun the gates.** The type check, lint and test suite run again in CI on the pull request, outside the agent's session, so a claimed green run is confirmed independently.
4. **Read only the high-risk parts.** Auth checks, migrations and anything touching money still get a human read. Everything else is judged on tests and gates.

You sign off on the acceptance criteria before the work and on the evidence after it. [The evidence bundle](/en/workflows/ship/evidence-bundle/) defines what a pull request from an agent must carry so that the reviewer can do the same.

## Where should Cursor prompt templates live: skill or rule?

A template pasted from a notes app drifts. Store each one in the repository, in the home that matches how it is used.

| Use | Home | How it is triggered | Shared across tools |
| --- | --- | --- | --- |
| A task you start by hand, such as "new endpoint" | Agent Skill (`SKILL.md`) | You name the skill in your prompt | The `skills` CLI installs the same folder for Claude Code and Codex |
| A procedure the agent should pick up without being asked | Agent Skill with a precise `description` | The agent matches its description to the task | The same |
| A constraint on every edit to certain files | Project rule in `.cursor/rules/` | Automatically, by file pattern or always | Cursor only |

A useful split: constraints that never change, such as "use `AppError` in routes", go in a rule, which keeps each template short and task-specific.

### Package a template as an Agent Skill

An Agent Skill is a folder with a `SKILL.md` whose frontmatter carries a `name` and a `description`. The agent reads the description in every session and loads the body only when the task matches, or when you name the skill. Keep the source in one folder of the repository, for example `skills/api-endpoint/SKILL.md`:

```markdown
---
name: api-endpoint
description: Add a REST endpoint to this service with tests first, the users.ts route pattern and the standard verification commands. Use when asked to add or change an API route.
---

1. Restate the acceptance criteria as tests in src/routes/__tests__/ and run them to see them fail.
2. Implement following src/routes/users.ts and src/lib/errors.ts.
3. Never edit existing tests or existing endpoints.
4. Run `npx vitest run src/routes`, `npx tsc --noEmit` and `npm run lint`.
5. Report files changed and the output of each command.
```

Then install it for every agent with the `skills` CLI (1.7.0, checked on 2026-09-26):

```bash
npx skills add ./skills --skill api-endpoint -a cursor -a claude-code -a codex -y
```

The `-y` flag skips the confirmation prompts. The CLI copies the skill into `.agents/skills/`, which Cursor and Codex read, and links `.claude/skills/` to that copy for Claude Code (skills 1.7.0, checked 2026-09-26). The copy does not follow later edits to `skills/`: rerun the same `npx skills add` command after every change, or keep the source in `.agents/skills/api-endpoint/` and edit it there. To share a skill across repositories, publish the folder on GitHub and install it with `npx skills add OWNER/REPO --skill api-endpoint -y` and the same `-a` flags. For structure, testing and publishing, see [building your own skills](/en/ecosystem/skills/building-custom-skills/).

To run the template by hand, name the skill with the task: `Use the api-endpoint skill: POST /api/orders returns 201 with the created order and 400 on an invalid body.`

Some teams keep hand-started templates as slash commands in `.cursor/commands/`. Cursor plugins can also bundle commands: the plugin docs say plugins "package rules, skills, agents, commands, MCP servers, and hooks". For a template that lives in your repository, write a skill instead, so that one file serves all three agents.

### Turn a recurring constraint into a project rule

A rule applies without being asked. Create a rule in `.cursor/rules/` for API route conventions and scope it to `src/routes/**/*.ts`, so that it applies only when the agent edits route files. Its body is a short list of constraints:

```markdown
- Validate every request body with a Zod schema from src/schemas/.
- Wrap handlers in withAuth unless the route is listed as public in src/routes/public.ts.
- Return errors only through AppError from src/lib/errors.ts.
```

Rule types, file-pattern scoping and the file format are covered in [project rules in Cursor](/en/cursor-ide/quick-start/project-rules/); a team-wide rules library is in [custom rules and templates](/en/cursor-ide/automate/custom-rules-templates/).

## When prompt templates stop working

**The output ignores your conventions.** The anchor file was renamed, deleted or no longer shows the current pattern. Open each `@` reference in the template, and point it at the file you would show a new hire today.

**The agent follows the first half of the template and drops the rest.** The template carries too many standing constraints. Move the ones that apply to every task into a rule, and keep the template to the task, anchor, boundaries, verification and report.

**The report says "all tests pass" but CI is red.** The agent summarised instead of running the command, or ran a narrower command than the one you named. Require the literal last lines of output in the report, and treat CI as the deciding run.

**Tests changed to make the task green.** The boundary said "Do NOT edit tests" and the agent edited them anyway, usually to match its own implementation. Reject the change, restore the tests with `git checkout main -- <test paths>`, and rerun. Then lock the test paths as described in [protecting the oracle](/en/workflows/test/protect-the-oracle/).

**The same template exists as a skill, a `.cursor/commands/` file and a pasted note, and they disagree.** Keep one source folder, reinstall it with `npx skills add … -y` after every change (or edit `.agents/skills/` directly), delete the others, and review template changes in pull requests like any other code.

**A template is too rigid for the task in front of you.** Delete the parts that do not apply and add what the task needs. If you make the same edit three times, update the template itself.

## Where to go next with Cursor prompt templates

- [Context management in Cursor](/en/cursor-ide/quick-start/context-management/): choosing the `@` references that anchor a template.
- [Project rules in Cursor](/en/cursor-ide/quick-start/project-rules/): the standing constraints that keep templates short.
- [Executable acceptance criteria](/en/workflows/plan/acceptance-criteria/): writing the criteria that open every feature template.
- [Protecting the oracle](/en/workflows/test/protect-the-oracle/): making "do not edit the tests" enforceable.
- The same library for other tools: [prompt engineering in Claude Code](/en/claude-code/build/prompt-engineering/) and [prompt engineering in Codex](/en/codex/build/prompt-engineering/).
