Cursor can generate GraphQL schema changes that break existing clients by removing fields, changing types, or renaming operations without deprecation. By adding .cursor/rules/ with backward compatibility requirements, referencing your existing schema with @file, and prompting with explicit versioning constraints, you can ensure Cursor generates additive-only schema changes that maintain API contracts with existing consumers.
Preventing breaking API contracts with Cursor
GraphQL APIs promise stability to clients through their schema contract. When Cursor modifies a schema, it can remove fields, change return types, or rename operations without understanding that existing clients depend on the current shape. This tutorial configures Cursor to treat your GraphQL schema as a contract and generate only additive, non-breaking changes.
Prerequisites
- Cursor installed with a GraphQL project
- An existing GraphQL schema file
- Basic understanding of GraphQL schema design
- Familiarity with Cursor Chat (Cmd+L) and project rules
Step-by-step guide
Create a GraphQL backward compatibility rule
Create a GraphQL backward compatibility rule
Add a project rule that enforces additive-only schema changes. This rule prevents Cursor from removing fields, changing types, or making required arguments optional. It also mandates @deprecated directives instead of removals.
1---2description: Enforce backward-compatible GraphQL schema changes3globs: "*.graphql,*.gql,*.resolver.ts,*.schema.ts"4alwaysApply: true5---67# GraphQL API Contract Rules8- NEVER remove existing fields from a type9- NEVER change the return type of an existing field10- NEVER rename existing queries, mutations, or subscriptions11- NEVER make a previously optional argument required12- ALWAYS add new fields instead of modifying existing ones13- ALWAYS use @deprecated(reason: "...") before removing fields14- New required arguments must have default values15- New enum values are safe to add16- Breaking changes require a new API version (v2)1718## Safe Changes (ALLOWED):19- Adding new fields to existing types20- Adding new queries, mutations, subscriptions21- Adding new types, enums, unions22- Adding optional arguments to existing fields23- Deprecating fields with @deprecated2425## Breaking Changes (NEVER without versioning):26- Removing any field, type, or operation27- Changing a field's return type28- Making optional arguments required29- Removing enum valuesExpected result: Cursor generates additive-only GraphQL schema changes and uses @deprecated for field removals.
Reference the existing schema when making changes
Reference the existing schema when making changes
Always reference your current schema file with @file when asking Cursor to modify the API. This gives Cursor the full picture of existing fields, types, and operations that must not be broken.
1@graphql-compat.mdc @src/schema/schema.graphql23Add a new 'analytics' section to the User type:41. Add lastLoginAt: DateTime field52. Add loginCount: Int field63. Add a new UserAnalytics type with detailed metrics74. Add a userAnalytics(userId: ID!): UserAnalytics query89Do NOT modify or remove any existing fields on the User type.10All changes must be additive only.Pro tip: Start every GraphQL prompt with 'Do NOT modify or remove any existing fields.' This is the single most effective instruction for preventing breaking changes.
Expected result: Cursor adds new fields and types without touching any existing schema definitions.
Generate deprecation notices for fields being phased out
Generate deprecation notices for fields being phased out
When you need to eventually remove a field, ask Cursor to add a @deprecated directive with a reason and migration path. This gives clients time to update while maintaining backward compatibility during the transition.
1@graphql-compat.mdc @src/schema/schema.graphql23Deprecate these fields (do NOT remove them):41. User.fullName -> deprecated in favor of User.displayName52. Query.getUser -> deprecated in favor of Query.user63. User.avatarUrl -> deprecated in favor of User.avatar.url78Add @deprecated directives with clear reasons and migration paths.9Add the new replacement fields/queries alongside the deprecated ones.10Both old and new must work simultaneously.Expected result: Cursor adds @deprecated directives to old fields and creates new replacement fields, keeping both functional.
Validate schema changes with a compatibility check
Validate schema changes with a compatibility check
Use Cursor Chat to compare your proposed schema changes against the existing schema and identify any breaking changes before they reach production.
1@graphql-compat.mdc @src/schema/schema.graphql @src/schema/schema-proposed.graphql23Compare the existing schema with the proposed changes.4Identify any breaking changes:51. Fields removed from any type62. Return types changed on existing fields73. Required arguments added without defaults84. Enum values removed95. Types renamed or removed1011For each breaking change found, explain the impact on existing12clients and suggest a backward-compatible alternative.Expected result: Cursor identifies breaking changes in the proposed schema and suggests backward-compatible alternatives.
Generate resolver updates that maintain both old and new fields
Generate resolver updates that maintain both old and new fields
When adding replacement fields alongside deprecated ones, both need working resolvers. Ask Cursor to generate resolvers that serve both the old and new schema simultaneously.
1@graphql-compat.mdc @src/schema/schema.graphql @src/resolvers/user.resolver.ts23Update the User resolver to support both deprecated and new fields:41. fullName (deprecated) — still returns firstName + lastName52. displayName (new) — returns the preferred display name63. avatarUrl (deprecated) — still returns the URL string74. avatar (new) — returns { url, width, height, format }89Both old and new resolvers must work simultaneously.10Share logic between deprecated and new resolvers to avoid duplication.Expected result: Cursor generates resolvers that serve both deprecated and new fields with shared logic to avoid duplication.
Complete working example
1---2description: Enforce backward-compatible GraphQL schema changes3globs: "*.graphql,*.gql,*.resolver.ts,*.schema.ts"4alwaysApply: true5---67# GraphQL API Contract Rules89## Core Principle:10The GraphQL schema is a CONTRACT with clients. Every change must be backward-compatible.1112## NEVER (Breaking Changes):13- Remove existing fields from any type14- Change the return type of an existing field15- Rename existing queries, mutations, or subscriptions16- Make previously optional arguments required17- Remove values from enums18- Remove types that are used in any operation1920## ALWAYS (Safe Changes):21- ADD new fields to existing types22- ADD new queries, mutations, subscriptions23- ADD new types, enums, unions, interfaces24- ADD optional arguments with default values25- USE @deprecated(reason: "Use newField instead") before removal2627## Deprecation Pattern:28```graphql29type User {30 fullName: String @deprecated(reason: "Use displayName instead")31 displayName: String32}33```3435## Versioning:36- Minor changes: additive fields, new operations37- Major changes (breaking): require /v2 API version38- Deprecated fields: minimum 6-month deprecation windowCommon mistakes when preventing Breaking API Contracts with Cursor
Why it's a problem: Asking Cursor to 'refactor' a GraphQL schema without specifying backward compatibility
How to avoid: Use 'extend' or 'add to' instead of 'refactor'. Always include 'do not remove or modify existing fields' in the prompt.
Why it's a problem: Not referencing the existing schema when requesting changes
How to avoid: Always reference your schema file with @file so Cursor sees the complete current state before suggesting changes.
Why it's a problem: Removing deprecated fields immediately after adding replacements
How to avoid: Add a rule specifying a minimum deprecation period (e.g., 6 months). Only remove fields after confirming no clients still use them.
Best practices
- Always reference the current schema with @file before requesting changes
- Use additive language in prompts: add, extend, augment — not refactor, restructure, replace
- Add @deprecated with clear reasons and migration paths before removing any field
- Generate resolvers for both old and new fields to support the transition period
- Validate proposed schema changes with a compatibility check prompt before implementing
- Keep a changelog of schema changes committed alongside the schema file
- Test schema changes against existing GraphQL client queries before deploying
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I need to add user analytics fields to my GraphQL User type without breaking existing clients. Show me how to add new fields, deprecate old ones with @deprecated directives, and maintain backward compatibility. Include resolver updates.
@graphql-compat.mdc @src/schema/schema.graphql Add order tracking fields to the existing Order type. Add a new OrderTracking type with status history. All changes must be additive only. Do NOT modify or remove any existing fields. Use @deprecated for any fields being replaced.
Frequently asked questions
Can I use GraphQL schema linting to catch breaking changes?
Yes. Tools like graphql-schema-linter and GraphQL Inspector can diff schemas and flag breaking changes in CI. Configure these alongside Cursor rules for defense in depth.
How do I handle required field additions?
New required fields must have default values or be nullable initially. Add the field as optional first, backfill existing data, then make it required in a later release.
What about union and interface changes?
Adding new types to a union is safe. Removing types from a union is breaking. Adding fields to an interface is breaking for implementors. Add these specifics to your rules.
How long should I keep deprecated fields?
Industry standard is 6-12 months. Monitor field usage through GraphQL analytics before removing. Add the minimum period to your rules file.
Does this apply to REST APIs too?
The same principles apply: additive changes only, deprecation before removal, versioning for breaking changes. Adjust the rules for REST-specific patterns like URL versioning.
Can RapidDev help design our API evolution strategy?
Yes. RapidDev designs API versioning strategies, sets up schema validation in CI, and configures Cursor rules to maintain backward compatibility across GraphQL and REST APIs.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation