Free tool

Generate .cursorrules for your stack

Select your framework, database, styling, and preferences. Get a production-ready .cursorrules file with 50–100+ lines of real, opinionated rules — not a skeleton.

Your stack

Select your tools and preferences.

Your primary web framework.

Language and strictness level.

Database and ORM.

CSS approach.

Auth strategy.

Test framework.

Programming paradigm preference.

.cursorrules

.cursorrules.markdown
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
  119. 119
  120. 120
  121. 121
  122. 122
  123. 123
  124. 124
  125. 125
  126. 126
# Project Identity
This is a Remix project using TypeScript (strict mode).
Database: PostgreSQL + Prisma.
Styling: Tailwind CSS.
Auth: Custom (session-based).
Testing: Vitest.
Programming paradigm: Functional-first.
When generating code, always respect the stack described above.
Never suggest libraries or patterns that conflict with these choices.
# Code Style
- Use descriptive variable names. Avoid abbreviations unless universally understood (e.g. `id`, `url`, `ctx`).
- Keep functions short. If a function exceeds ~30 lines, extract sub-functions.
- One export per file for primary modules. Co-locate helpers in the same file when they are tightly coupled.
- Prefer early returns over nested conditionals.
- Naming conventions:
- Functions and variables: camelCase
- Types and interfaces: PascalCase
- Constants: UPPER_SNAKE_CASE for true constants, camelCase for derived values
- Files: kebab-case for all files
- Always provide explicit return types for exported functions.
- Prefer `type` over `interface` unless you need declaration merging.
- Use `as const` for literal objects that should not be widened.
- Use `readonly` for arrays and object properties that should not be mutated.
- Never use `any`. Use `unknown` and narrow with type guards.
- Enable all strict compiler flags: strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes.
# Programming Paradigm: Functional-First
- Prefer pure functions. Given the same input, always return the same output. No side effects.
- Data is immutable. Never mutate function arguments. Return new objects/arrays.
- Use composition over inheritance. Build complex behavior by combining simple functions.
- Avoid classes. Use plain objects and functions. Types describe shape, functions transform data.
- Side effects (database, API calls, logging) happen at the edges, not in core logic.
- Use higher-order functions (map, filter, reduce) over imperative loops.
- Avoid closures that encapsulate mutable state — this is object-oriented programming in disguise.
- State is data. Functions transform data into new data. Separate state from behavior.
# Architecture
- Separate concerns: data access, business logic, and presentation are distinct layers.
- Keep side effects at the edges. Core logic should be pure and testable.
- Do not put business logic in route handlers or components. Extract it into dedicated modules.
- Avoid circular dependencies. If two modules depend on each other, extract shared types/utilities.
- Group files by feature, not by type. Co-locate related files (component + styles + tests + types).
- Use Remix file-based routing conventions. Nested routes for layout composition.
- Loaders for data fetching. Actions for mutations. Never fetch data in components.
- Keep server-only code in .server.ts files. Never import server modules from client code.
- Use `invariant` or `invariantResponse` for runtime assertions in loaders/actions.
- Prefer `useFetcher` for non-navigation mutations. Use `useSubmit` for navigation-triggering actions.
- Return proper HTTP status codes from loaders and actions (400, 401, 403, 404, etc).
- Use resource routes for API endpoints (routes that export loader/action but no default component).
# Database
- Never write raw SQL unless the ORM cannot express the query. Document why raw SQL was necessary.
- All database access through a single module (e.g. db.ts or db.server.ts). No scattered Prisma/Mongoose calls.
- Validate data before writing to the database. The database is the last line of defense, not the first.
- Use transactions for operations that modify multiple tables.
- Never trust user input in queries. Always use parameterized queries or ORM methods.
- Use Prisma migrations for all schema changes. Never use `prisma db push` in production.
- Define explicit relations with @relation directives. Name relations when a model has multiple references to the same table.
- Use Prisma's `select` and `include` to fetch only needed fields. Avoid fetching entire records when you only need a few columns.
- Use `createMany`, `updateMany` for batch operations. Avoid N+1 query patterns.
- Add database indexes for columns used in WHERE, ORDER BY, and JOIN clauses.
# Styling
- Use Tailwind utility classes directly in markup. Avoid @apply in CSS files.
- Extract repeated class combinations into components, not CSS abstractions.
- Use Tailwind's design system: spacing scale, color palette, typography. Avoid arbitrary values unless necessary.
- Responsive design: mobile-first with sm:, md:, lg: breakpoint prefixes.
- Dark mode: use the dark: variant consistently. All UI must work in both modes.
- Group Tailwind classes logically: layout → spacing → sizing → typography → colors → effects.
# Authentication & Authorization
- Auth checks happen at the route/middleware level, not in components.
- Never expose auth tokens, session IDs, or secrets to client-side code.
- Always validate sessions server-side. Never trust client-provided auth state.
- Sessions stored server-side (database or encrypted cookie). Never store sensitive data in plain cookies.
- Implement CSRF protection for all state-changing requests.
- Session expiry and rotation: regenerate session ID after login. Set reasonable expiry times.
- Rate-limit login attempts. Implement account lockout or progressive delays.
- Hash passwords with bcrypt or argon2. Never store plain-text passwords.
# Security
- Validate and sanitize all user input at the boundary (route handlers, API endpoints).
- Use environment variables for secrets. Never commit .env files. Add .env to .gitignore.
- Set security headers: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options.
- HTTPS only in production. Redirect HTTP to HTTPS.
- Escape all user-generated content rendered in HTML to prevent XSS.
- Use parameterized queries or ORM methods to prevent SQL injection.
- Implement rate limiting on authentication and public API endpoints.
- Keep dependencies updated. Run `npm audit` regularly.
- Never log sensitive data (passwords, tokens, PII).
# Testing
- Co-locate test files with the code they test: component.test.ts next to component.ts.
- Test names describe behavior, not implementation: "redirects unauthenticated users" not "calls redirect function".
- Arrange-Act-Assert pattern for all tests.
- Test the public API, not internal implementation details. If you refactor internals, tests should still pass.
- Mock external dependencies (database, APIs, third-party services). Never mock the code under test.
- Use Vitest's `describe`/`it`/`expect` API. Prefer `it` over `test` for consistency.
- Use `vi.mock()` for module mocking. Reset mocks between tests with `afterEach(() => vi.restoreAllMocks())`.
- Use `vi.fn()` for function spies and stubs.
- Prefer inline snapshots (`toMatchInlineSnapshot`) over file snapshots for small outputs.
- Configure test coverage thresholds in vitest.config.ts.
# AI Coding Guidance
- When asked to implement something, read the existing code first. Understand patterns before writing.
- Prefer editing existing files over creating new ones. Avoid file proliferation.
- Do not add features, refactoring, or "improvements" beyond what was asked.
- Do not add comments to code you did not change. Only add comments where the logic is not self-evident.
- Do not add error handling for scenarios that cannot happen. Trust internal code and framework guarantees.
- Do not create abstractions for one-time operations. Three similar lines are better than a premature abstraction.
- When in doubt about the approach, ask. Do not guess.
- After making changes, verify they work. Run tests, check types, and confirm the output.
- Keep changes minimal and focused. A small, correct change is better than a large, speculative one.
- Never introduce security vulnerabilities. Validate user input, escape output, use parameterized queries.

Skip the generator. Ship with guardrails built in.

LaunchFast ships with battle-tested AI guardrails — cursor rules, CLAUDE.md, and architectural constraints that keep AI assistants correct as you build. No generator needed.