
Cursor Rules: Sådan skriver du .cursor/rules-filer, der faktisk virker
Alle Cursor-brugere støder på den samme mur. AI'en genererer kode, der teknisk set virker, men ignorerer dit projekts konventioner, bruger forkerte import-stier, forældede mønstre eller strukturerer komponenter helt anderledes end resten af din kodebase. Cursor rules løser dette ved at give AI'en vedvarende kontekst om, hvordan dit projekt fungerer.
Hvad er Cursor Rules, og hvorfor betyder de noget?
Cursor rules er markdown-filer, der fungerer som en permanent system-prompt, der indsættes før hver AI-interaktion – chat, autoudfyldelse, kodegenerering, det hele. Tænk på dem som onboarding-dokumentation for AI'en. I stedet for at rette de samme fejl hver session, skriver du instruktionen én gang, og så hænger den ved.
Den gamle tilgang var en enkelt .cursorrules-fil i projektroden. Det virker stadig, men det er udgået (deprecated). Det nuværende system bruger en .cursor/rules/-mappe med individuelle .mdc-filer (Markdown Cursor), hvor hver fil er scoped til specifikke situationer. Dette er en meget bedre opsætning, fordi du ikke propper alle instruktioner ind i én kæmpe fil; du opdeler reglerne efter ansvarsområde, og Cursor indlæser kun dem, der er relevante for det, du laver lige nu.
Hvis du har arbejdet med context engineering til AI-værktøjer, vil konceptet være bekendt: bedre input-kontekst producerer markant bedre output. Rules er context engineering for hele din udviklingsworkflow.
Opsætning af din første regelfil
Opret mappen .cursor/rules/ i din projektrod:
mkdir -p .cursor/rulesHver regel er en .mdc-fil med YAML frontmatter efterfulgt af markdown-indhold. Her er skelettet:
---
description: "When this rule should apply"
globs: ["src/components/**/*.tsx"]
alwaysApply: false
---
Your instructions go here in plain markdown.Tre frontmatter-felter styrer alt:
| Felt | Type | Formål |
|---|---|---|
alwaysApply | boolean | Inkluderes i hver AI-anmodning, når true |
description | string | Hjælper agenten med at afgøre, om denne regel er relevant |
globs | string[] | Fil mønstre, der udløser denne regel |
Du kan også oprette regler direkte gennem Cursor: skriv /create-rule i chatten og beskriv, hvad du ønsker. Men ved at skrive dem manuelt får du mere kontrol.
De fire regeltyper forklaret
Hvordan en regel aktiveres, afhænger af dens frontmatter-konfiguration. Der er fire tilstande, og valget af den rigtige type er afgørende for dit context window-budget.
Always Apply (Anvend altid)
---
alwaysApply: true
---Indlæses i hver eneste AI-anmodning. Brug dette sparsomt, til projektvide fundamentaler som erklæring af tech stack eller kritiske konventioner, der gælder overalt. Hver "always-on"-regel æder tokens fra hver interaktion, uanset om den er relevant eller ej.
Auto-Attached (Glob-baseret)
---
globs: ["src/api/**/*.ts", "src/routes/**/*.ts"]
alwaysApply: false
---Aktiveres kun, når du redigerer filer, der matcher glob-mønstrene. Dette er arbejdshesten blandt regeltyper. Dine React-komponentkonventioner indlæses, når du er i komponentfiler, dine API-mønstre indlæses, når du er i route handlers, og dine testregler indlæses, når du skriver tests.
Agent-Requested (Intelligent)
---
description: "Database migration patterns using Drizzle ORM"
alwaysApply: false
---Ingen globs, ingen always-apply, kun en beskrivelse. Cursors agent læser beskrivelsen og beslutter, om reglen er relevant for den aktuelle opgave. Hvis du beder den om at skrive en migration, henter den denne regel. Hvis du styler en knap, springer den den over. Dette virker overraskende godt til regler, der ikke kortlægges pænt til filstier.
Manual (Manuel)
---
---Ingen frontmatter-felter sat (eller tom frontmatter). Disse regler aktiveres kun, når du eksplicit nævner dem med @rule-name i chatten. Godt til sjældent brugte, men vigtige instruktioner, som deployments-tjeklister eller refactoring-guides, du kun har brug for lejlighedsvis.
| Regeltype | Hvornår indlæses den? | Bedst til |
|---|---|---|
| Always Apply | Hver anmodning | Tech stack, kritiske konventioner |
| Auto-Attached | Ved åbning af matchende fil | Framework-mønstre, filtype-regler |
| Agent-Requested | Agenten beslutter | Krydsende bekymringer, workflows |
| Manual | Ved @-omtale | Engangsopgaver, tjeklister |
Glob-mønstre, der faktisk virker
Globs bestemmer, hvilke filer der udløser auto-attached regler. Får du dem forkert, udløses dine regler enten aldrig eller overalt. Her er, hvad der virker:
# All TypeScript files in src
globs: ["src/**/*.ts", "src/**/*.tsx"]
# Only component files
globs: ["**/components/**/*.tsx"]
# Python files, excluding tests
globs: ["**/*.py", "!**/test_*.py"]
# Multiple specific directories
globs: ["src/api/**", "src/services/**"]Nogle faldgruber fra reel brug:
src/*matcher kun ét mappeniveau. Du vil næsten altid havesrc/**/*for rekursiv matching.*.jsmatcher ikke.jsx- eller.ts-filer. Vær eksplicit omkring filtypenavne.- Globs skal være en YAML-liste. Krøllesyntax som
{src,lib}/**/*.tskan fejle stille, så hold dig til separate listeposter. - Præfikset
!ekskluderer mønstre, hvilket er nyttigt til at ignorere genererede filer eller legacy-kode.
Praktiske regeleksempler
Her møder teori virkeligheden. Dette er regler, du kan smide ind i et projekt og straks se bedre AI-output.
Projektvid base-regel (Always Apply)
---
alwaysApply: true
---
# Project: Acme Dashboard
## Tech Stack
- Next.js 15 (App Router only — no Pages Router)
- TypeScript strict mode
- Tailwind CSS v4
- Drizzle ORM with PostgreSQL
- pnpm for package management
## Critical Conventions
- All components are React Server Components by default
- Use "use client" only when the component needs interactivity
- Import paths use @/ alias mapped to src/
- Error handling: wrap async operations in try/catch, never use .catch()
- No default exports except for pages and layoutsHold dette under 30 linjer. Det indlæses med hver anmodning, så hvert ord koster tokens.
React-komponentregel (Auto-Attached)
---
description: "React component patterns and conventions"
globs: ["src/components/**/*.tsx", "src/app/**/*.tsx"]
alwaysApply: false
---
# React Component Rules
## Structure
Every component file follows this order:
1. Imports
2. Type definitions (Props interface)
3. Component function (named export)
4. Sub-components (if any)
## Patterns
Use named exports, not default:
- YES: `export function Button({ label }: ButtonProps)`
- NO: `export default function Button()`
For data fetching in Server Components:
```tsx
// Fetch direkte i komponenten, ingen useEffect
export async function UserProfile({ id }: { id: string }) {
const user = await db.query.users.findFirst({
where: eq(users.id, id)
});
return <div>{user.name}</div>;
}Anti-Patterns (NEVER do these)
- No useEffect for data fetching in Server Components
- No CSS modules — use Tailwind exclusively
- No barrel exports (index.ts re-exports)
- No prop drilling beyond 2 levels — use context or composition
### Python API-regel (Auto-Attached)
```yaml
---
description: "FastAPI endpoint conventions and patterns"
globs: ["src/api/**/*.py", "src/routes/**/*.py"]
alwaysApply: false
---
# FastAPI Conventions
## Endpoint Structure
- Use APIRouter for route grouping
- Type all request/response models with Pydantic v2
- Dependency injection for database sessions
## Pattern
```python
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
user_id: int,
db: AsyncSession = Depends(get_db)
) -> UserResponse:
user = await db.get(User, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return UserResponse.model_validate(user)Error Handling
- Always use HTTPException, not raw Response objects
- Log errors with structlog before raising
- Return consistent error shapes: {"detail": "message"}
### Go Service-regel (Auto-Attached)
```yaml
---
description: "Go service patterns and error handling"
globs: ["**/*.go", "!**/*_test.go"]
alwaysApply: false
---
# Go Conventions
## Error Handling
- Always handle errors immediately — no _ for error returns
- Wrap errors with fmt.Errorf("context: %w", err)
- Use sentinel errors for expected failure cases
## Project Layout
- cmd/ for entrypoints
- internal/ for private packages
- pkg/ for public libraries
## Pattern
```go
func (s *UserService) GetByID(ctx context.Context, id string) (*User, error) {
user, err := s.repo.Find(ctx, id)
if err != nil {
if errors.Is(err, ErrNotFound) {
return nil, fmt.Errorf("user %s: %w", id, ErrNotFound)
}
return nil, fmt.Errorf("fetching user %s: %w", id, err)
}
return user, nil
}
## Håndtering af "Token-skatten"
Her er noget, de fleste Cursor-guides springer over: hver regel, du skriver, koster tokens. Et projekt med 20 always-on regler kan brænde **2.000+ tokens per anmodning** alene på instruktioner, før AI'en overhovedet kigger på din kode.
Det betyder noget, fordi Cursors chat-kontekst er cirka 20.000 tokens i standardtilstand. Hvis dine regler æder 25 % af det, har du mistet en fjerdedel af AI'ens "tænkeplads" til dit egentlige spørgsmål. Du vil bemærke dårligere output-kvalitet, efterhånden som reglerne hober sig op, især i længere samtaler.
Tre principper holder dit token-budget sundt:
**1. Brug auto-attached og agent-requested regler aggressivt.** Kun din projekt-stack-erklæring bør være always-on. Alt andet bør indlæses betinget. Den React-komponentregel? Den behøver ikke være i kontekst, når du skriver SQL-migrationer.
**2. Skriv tæt, ikke fyldigt.** Erstat "Det anbefales stærkt, at udviklere bruger TypeScript interfaces frem for type aliases, når de definerer offentlige API-kontrakter" med "Foretræk `interface` frem for `type` til offentlige APIs." AI'en har ikke brug for overtalelse, den har brug for instruktioner.
**3. Anvend tre-reglen.** Kodificér kun et mønster som en regel, efter at AI'en har lavet fejlen tre gange. Hvis Cursor allerede håndterer dine navngivningskonventioner korrekt uden en regel, så spring reglen over. Hver unødvendig regel er spildt kontekst.
Du kan overvåge token-forbrug i statuslinjen nederst i Cursors chatpanel. Hold øje med, hvis det nærmer sig 100 % – det er dit signal til at rydde op.
## Organisering af regler til et rigtigt projekt
Et produktionsprojekt har typisk brug for 5-8 regelfiler. Her er en struktur, der virker godt:
```text
.cursor/rules/
base.mdc # Tech stack, always-apply (< 30 lines)
components.mdc # React/Vue patterns, glob to component dirs
api.mdc # Backend conventions, glob to API dirs
database.mdc # ORM patterns, glob to models/migrations
testing.mdc # Test conventions, glob to test files
deployment.mdc # CI/CD patterns, manual trigger
personal.mdc # Your preferences (gitignored)Commit alt til versionskontrol undtagen personal.mdc. På den måde får hele dit team den samme AI-adfærd, hvilket er hele pointen. Som en bruger på Cursor-forummet siger det: gode regler betyder, at "du accepterer flere forslag, som de er, med output der matcher dine konventioner i første forsøg."
Hvis du arbejder med andre AI-kodningsværktøjer sammen med Cursor, overføres koncepterne direkte. Claude Code bruger CLAUDE.md, GitHub Copilot har instruktionsfiler, og Windsurf har sit eget format, men det underliggende princip er identisk.
Hvordan regel-præcedens virker
Når flere regler gælder for den samme fil, følger Cursor en klar hierarki:
| Prioritet | Kilde | Tilsidesættelsesadfærd |
|---|---|---|
| 1 (højeste) | Team Rules (dashboard) | Kan ikke deaktiveres af brugere |
| 2 | Project Rules (.cursor/rules) | Tilsidesætter brugerregler |
| 3 | User Rules (Cursor-indstillinger) | Globale standarder |
Team rules er tilgængelige på Team- og Enterprise-planer. De sættes i Cursor-dashboardet af administratorer og håndhæves på tværs af organisationen; individuelle udviklere kan ikke slukke for dem.
Inden for projektregler, hvis to regler gælder for den samme fil og er i konflikt, er adfærden ikke strengt defineret. I praksis har regler, der indlæses senere, tendens til at have forrang. Nummerering af dine filer (001-base.mdc, 002-components.mdc) giver dig forudsigelig rækkefølge.
Almindelige fejl og hvordan man retter dem
Efter at have læst snesevis af community-tråde og testet regler på tværs af projekter, er her de fejl, der oftest driller folk:
Skrivning af regler, der er for vage. "Skriv ren kode" fortæller AI'en ingenting. "Brug named exports, ikke default exports. Strukturér komponenter som: imports, types, function, sub-components" giver den noget handlbart.
At gøre alt til always-apply. Din første instinkt er at sætte alwaysApply: true på hver regel. Modstå det. Revider dine regler kvartalsvist; hvis du har mere end 2-3 always-on regler, spilder du sandsynligvis tokens.
Glemme at teste regler. Efter at have skrevet en regel, skal du åbne en relevant fil og bede Cursor om at generere noget, der bør følge reglen. Hvis det ikke gør det, kan dit glob-mønster være forkert, eller instruktionen er ikke klar nok.
Ikke at dokumentere anti-mønstre. At fortælle AI'en, hvad den skal gøre, er halvdelen af jobbet. At fortælle den, hvad den ikke skal gøre, er den anden halvdel. Inkluder en sektion "ALDRIG gør disse" i hver regel med eksplicitte eksempler på den forkerte tilgang.
Ignorere regel-gemning i UI'en. En kendt bug får regelændringer til at forsvinde. Hvis ændringer forsvinder, skal du lukke Cursor helt, vælge "Override" i popup'en om ikke-gemte ændringer og genåbne.
Cursor Rules vs CLAUDE.md vs AGENTS.md
Cursor er ikke det eneste værktøj, der bruger instruktionsfiler. Her er en sammenligning af formaterne for alle, der arbejder på tværs af flere AI-kodningsassistenter:
| Funktion | .cursor/rules | CLAUDE.md | AGENTS.md |
|---|---|---|---|
| Format | MDC med frontmatter | Almindelig markdown | Almindelig markdown |
| Glob-scoping | Ja | Nej | Mappe-niveau |
| Regeltyper | 4 (always, auto, agent, manual) | Always-on | Always-on |
| Token-kontrol | Finmaskét | Grov | Grov |
| Versionskontrol | Ja | Ja | Ja |
| Virker i | Kun Cursor | Claude Code | Flere værktøjer |
Cursors fordel er granularitet. CLAUDE.md og AGENTS.md er simplere; de indlæser alt altid. Cursor lader dig indlæse de rigtige regler på det rigtige tidspunkt, hvilket betyder noget, når dit instruktionssæt vokser ud over et par hundrede linjer.
For et dybere kig på, hvordan kontekst former AI-output på tværs af disse værktøjer, breaker vores guide til context engineering de principper ned, der gælder uanset hvilken editor du bruger.
FAQ
Er .cursorrules udgået?
Ja. Den enkelte .cursorrules-fil i din projektrod virker stadig, men Cursor anbefaler at migrere til .cursor/rules/*.mdc-filer. Det nye format understøtter glob-mønstre, betinget indlæsning og bedre organisering. Migrér ved at opdele din monolitiske fil i fokuserede regler.
Hvilken filendelse skal jeg bruge, .mdc eller .md?
Brug .mdc til filer, der inkluderer YAML frontmatter (description, globs, alwaysApply). Almindelige .md-filer virker også i rules-mappen, men understøtter ikke de frontmatter-metadata, der muliggør betinget indlæsning.
Hvor mange regler skal et projekt have?
Fem til otte er sweet spot for de fleste projekter. Én always-on base-regel, tre til fire auto-attached regler scoped efter filtype og en eller to manuelle regler til specielle opgaver. Mere end 10 regler betyder normalt, at nogle kan konsolideres eller fjernes.
Påvirker Cursor rules autoudfyldelse og tab-completion?
Regler gælder for chat- og agent-interaktioner. User Rules gælder ikke for inline-edits (Cmd/Ctrl+K), og regler påvirker generelt ikke Cursor Tabs autoudfyldelsesforslag. De er mest effektive i chat- og Composer-sessioner.
Kan jeg dele regler på tværs af flere projekter?
Ja, gennem Cursors Remote Rules-funktion. Gå til Cursor Settings > Rules, Commands, vælg "Remote Rule (GitHub)," og indsæt en repository-URL. Regler synkroniseres automatisk, når kilde-repoet opdateres. Alternativt kan du vedligeholde et delt rules-repo og symlinke det ind i hvert projekt.
Hvad er den maksimale anbefalede regellængde?
Cursors docs foreslår at holde individuelle regler under 500 linjer. I praksis bør du sigte mod under 100 linjer per regel. Kortere regler er lettere at vedligeholde og koster færre tokens. Hvis en regel overstiger 150 linjer, så del den op i to fokuserede regler.
Virker regler med alle AI-modeller i Cursor?
Regler virker med enhver model, Cursor understøtter, inklusive Claude, GPT-4o, Gemini og andre. Reglerne injiceres som system-level kontekst uanset hvilken model, du har valgt. Modeladfærd kan variere, men reglerne i sig selv er model-agnostiske.
Hvordan debugger jeg en regel, der ikke virker?
Først, verificér at glob-mønsteret matcher din fil; åbn filen og tjek, om reglen vises i kontekstpanelet. For det andet, test med et direkte spørgsmål, der bør udløse reglen. For det tredje, prøv at sætte alwaysApply: true midlertidigt for at bekræfte, at regelindholdet i sig selv virker. Hvis det gør det, ligger problemet i dit glob-mønster.
Skal jeg committe .cursor/rules til git?
Absolut. Hele pointen med projektregler er team-wide konsistens. Commit alt i .cursor/rules/ undtagen filer med personlige præferencer. Tilføj en personal.mdc til .gitignore for individuelle indstillinger, der ikke bør gælde for alle.
Kan jeg bruge Cursor rules sammen med MCP-servere?
Ja, og de supplerer hinanden godt. Regler definerer hvordan AI'en skal skrive kode, mens MCP-servere giver AI'en adgang til eksterne værktøjer og data. En regel kan sige "brug altid vores interne API-klient," mens en MCP-server lader AI'en faktisk query'e den API under udvikling.
Hvis AI-funktioner er på din roadmap, er det vores speciale: Techsys AI-integrationsteam bringer LLM-systemer fra prototype til produktion. Vil du have en second opinion på din stack? Få en gratis konsultation.