Skip to main content
RapidDev - Software Development Agency
cursor-tutorial

How to Make Cursor Respect Feature Flags

Cursor will generate feature-flag-aware code when you define your flag system in .cursorrules and provide the flag utility as @file context. Specify the flag names, the evaluation function signature, and whether flags are synchronous or async. Cursor then wraps new code paths in the correct flag check — keeping unreleased features hidden from production without manual wiring after generation.

What you'll learn

  • How to document your feature flag system in .cursorrules so Cursor wraps new code in the right flag checks
  • How to prompt Cursor to generate flag-gated React components and API routes
  • How to use @file to give Cursor your existing flag utility as a live reference
  • How to audit generated code for hard-coded feature logic that bypasses the flag system
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner9 min read15-20 minCursor Free+, any language or frameworkMarch 2026RapidDev Engineering Team
TL;DR

Cursor will generate feature-flag-aware code when you define your flag system in .cursorrules and provide the flag utility as @file context. Specify the flag names, the evaluation function signature, and whether flags are synchronous or async. Cursor then wraps new code paths in the correct flag check — keeping unreleased features hidden from production without manual wiring after generation.

Make Cursor respect feature flags in every generated code path

Feature flags gate unreleased code behind runtime checks — but Cursor does not know your flag system exists unless you tell it. Without guidance, Cursor generates straightforward code that executes unconditionally, leaving you to manually wrap each block in a flag check after the fact. This tutorial shows you how to configure .cursorrules and use @file context so that Cursor automatically calls your flag evaluation function wherever new features are introduced — front-end components, API routes, and service methods alike.

Prerequisites

  • Cursor installed (Free plan or above)
  • An existing feature flag system or utility (LaunchDarkly, Unleash, a home-grown isFeatureEnabled function, etc.)
  • Basic familiarity with .cursorrules and Cursor Chat (Cmd+L)

Step-by-step guide

1

Document your flag system in .cursorrules

Open or create .cursorrules. Add a section that names the flag evaluation function, its import path, the flag name format, and any async/sync requirements. List the active flag names so Cursor knows what values are legal. If you use an external SDK like LaunchDarkly, include the client initialisation pattern so Cursor imports correctly.

.cursorrules
1# .cursorrules
2
3## Feature Flags
4This project uses a centralized feature flag system. Follow these rules for ALL new code.
5
6### Flag evaluation
7- Import the flag hook from src/utils/featureFlags.ts
8- In React components: use const isEnabled = useFeatureFlag('FLAG_NAME')
9- In service/utility code: use isFeatureEnabled('FLAG_NAME') synchronous, reads from a global flag store
10- NEVER hard-code feature behaviour behind a plain boolean variable
11- NEVER inline flag logic always call the designated utility
12
13### Active flag names (as of March 2026)
14- 'new_checkout_flow' gates the redesigned checkout UI
15- 'ai_recommendations' gates the AI product recommendation widget
16- 'bulk_export' gates CSV bulk export on the orders page
17- 'beta_api_v2' gates v2 API endpoints on the backend
18
19### Flag name format
20- Always LOWER_SNAKE_CASE strings
21- NEVER use boolean literals to simulate flags
22
23### Pattern for React components
24if (!isEnabled) return null; // or return <LegacyComponent />
25
26### Pattern for API routes / service methods
27if (!isFeatureEnabled('FLAG_NAME')) {
28 return res.status(404).json({ error: 'Not available' });
29}

Pro tip: Keep the active flag list in .cursorrules up to date. When Cursor sees the valid flag names, it picks the right one automatically instead of inventing a new name.

Expected result: Cursor wraps new feature code in the correct flag check for every future prompt in this project.

2

Provide the flag utility as @file context

When asking Cursor to generate a flag-gated component or endpoint, always reference the flag utility file with @file. This gives Cursor the exact function signature, TypeScript types, and import path — eliminating guesswork about how to call the flag system. For React projects this is typically a custom hook; for Node.js it is a utility function.

src/utils/featureFlags.ts
1// src/utils/featureFlags.ts — reference this with @file in your prompts
2
3import { useContext } from 'react';
4import { FlagContext } from './FlagContext';
5
6export function useFeatureFlag(flagName: string): boolean {
7 const flags = useContext(FlagContext);
8 return flags[flagName] ?? false;
9}
10
11export function isFeatureEnabled(flagName: string): boolean {
12 // Server-side / non-React usage
13 return globalFlagStore.get(flagName) ?? false;
14}

Pro tip: If your flag utility is more complex (async, SDK-based), paste the actual function signatures into .cursorrules so Cursor has them even when you forget to include @file.

Expected result: You have a reference file ready to attach to any flag-related Cursor prompt.

3

Generate a flag-gated React component

Open Cursor Chat (Cmd+L) and ask for a new component that is controlled by a feature flag. Reference both the flag utility and an existing component as context. The prompt should name the specific flag, the fallback behaviour (render null, render the old component, or show a 'coming soon' placeholder), and the file path for the new component.

Cursor Chat prompt (Cmd+L)
1Using @file src/utils/featureFlags.ts:
2
3Generate a React component at src/components/AiRecommendations.tsx.
4This component renders an AI product recommendation widget.
5Requirements:
6- At the top of the component, call useFeatureFlag('ai_recommendations')
7- If the flag is false, return null do not render anything
8- If the flag is true, render the widget content
9- The widget shows a heading 'Recommended for you' and a grid of 4 ProductCard placeholders
10- Export as named export AiRecommendations

Pro tip: Specify the fallback explicitly: 'return null', 'return <LegacyWidget />', or 'return <ComingSoon />'. Without a fallback instruction, Cursor sometimes omits the guard entirely.

Expected result: AiRecommendations.tsx is generated with useFeatureFlag('ai_recommendations') at the top and returns null when the flag is disabled.

4

Generate a flag-gated API route

Use Cursor Chat to add feature flag protection to a new Express or Next.js API endpoint. For server-side code the synchronous isFeatureEnabled function is used instead of the React hook. Provide the flag name, the guarded route path, and the error response to return when the flag is off. Reference the flag utility with @file so Cursor imports from the correct path.

Cursor Chat prompt (Cmd+L)
1Using @file src/utils/featureFlags.ts:
2
3Generate a Next.js API route at src/app/api/export/route.ts for bulk CSV export.
4Requirements:
5- Check isFeatureEnabled('bulk_export') at the top of the GET handler
6- If false: return Response.json({ error: 'This feature is not available' }, { status: 404 })
7- If true: generate a CSV from a mock array of 5 order objects and return it as a file download
8- Use strict TypeScript, no 'any'

Expected result: The API route checks the bulk_export flag and returns a 404 response if disabled, or generates and returns CSV data if enabled.

5

Audit generated code for missing flag checks

After a scaffolding session, use @codebase in Cursor Chat to scan for new feature code that might be missing flag protection. Ask Cursor to look for components or routes that were recently added but do not call useFeatureFlag or isFeatureEnabled. This is a safeguard — even well-prompted Cursor sessions occasionally produce a helper function that bypasses the flag check.

Cursor Chat prompt (Cmd+L)
1Using @codebase:
2
3Scan all files modified or created in the last session in src/components/ and src/app/api/.
4Identify any components or API handlers that introduce new user-facing features but do NOT call useFeatureFlag() or isFeatureEnabled().
5List each file, the function or component name, and the suggested flag name based on the feature description.

Pro tip: Run this audit before each pull request. It takes seconds and prevents a feature from accidentally reaching production before the flag is ready to flip.

Expected result: Cursor lists any components or API handlers that are missing flag checks, with suggested flag names to add.

Complete working example

src/components/AiRecommendations.tsx
1import React from 'react';
2import { useFeatureFlag } from '../utils/featureFlags';
3
4interface Product {
5 id: string;
6 name: string;
7 price: number;
8 imageUrl: string;
9}
10
11interface ProductCardProps {
12 product: Product;
13}
14
15function ProductCard({ product }: ProductCardProps) {
16 return (
17 <div className="border rounded-lg p-4 flex flex-col gap-2">
18 <img src={product.imageUrl} alt={product.name} className="w-full h-40 object-cover rounded" />
19 <h3 className="font-semibold">{product.name}</h3>
20 <p className="text-gray-600">${product.price.toFixed(2)}</p>
21 </div>
22 );
23}
24
25const PLACEHOLDER_PRODUCTS: Product[] = [
26 { id: '1', name: 'Product A', price: 29.99, imageUrl: '/placeholder.png' },
27 { id: '2', name: 'Product B', price: 49.99, imageUrl: '/placeholder.png' },
28 { id: '3', name: 'Product C', price: 19.99, imageUrl: '/placeholder.png' },
29 { id: '4', name: 'Product D', price: 39.99, imageUrl: '/placeholder.png' },
30];
31
32export function AiRecommendations() {
33 const isEnabled = useFeatureFlag('ai_recommendations');
34
35 if (!isEnabled) {
36 return null;
37 }
38
39 return (
40 <section className="py-8">
41 <h2 className="text-2xl font-bold mb-6">Recommended for you</h2>
42 <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
43 {PLACEHOLDER_PRODUCTS.map((product) => (
44 <ProductCard key={product.id} product={product} />
45 ))}
46 </div>
47 </section>
48 );
49}

Common mistakes when making Cursor Respect Feature Flags

Why it's a problem: Not listing active flag names in .cursorrules

How to avoid: Maintain a list of active flag names in .cursorrules under '## Feature Flags'. Update it whenever a new flag is created or an old one is removed.

Why it's a problem: Asking Cursor to 'add a feature flag' without specifying the fallback behaviour

How to avoid: Always specify the fallback in your prompt: 'return null if the flag is false' or 'return the legacy component if the flag is false'.

Why it's a problem: Using a plain boolean prop to simulate feature flags

How to avoid: Add 'NEVER use boolean props to simulate feature flags — always call useFeatureFlag() or isFeatureEnabled()' to .cursorrules.

Why it's a problem: Forgetting to audit helper functions and not just the top-level component

How to avoid: Use the @codebase audit from Step 5 to check all recently modified files, not just the main component entry point.

Best practices

  • List all active feature flag names in .cursorrules so Cursor never invents a flag name that does not exist in your flag management system.
  • Standardise flag evaluation through a single utility (useFeatureFlag hook or isFeatureEnabled function) and reference it with @file in every flag-related prompt.
  • Always specify the fallback behaviour — return null, return legacy component, or return a 404 — when prompting for flagged code.
  • Run a @codebase audit for missing flag checks before every pull request, not just after large scaffolding sessions.
  • For A/B tests that need analytics, ask Cursor to also add a flag evaluation event: 'Call trackFlagEvaluation(flagName, isEnabled) after the flag check.'
  • Keep flag checks at the component or route level, not deep inside utility functions — this makes it easy to find and clean up when the flag is fully rolled out.
  • When a feature graduates to permanently on, use Composer to find and remove all flag checks for that flag at once: 'Remove all useFeatureFlag("old_flag") checks and always render the new code path.'

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a React TypeScript project with a useFeatureFlag(flagName: string): boolean hook imported from src/utils/featureFlags.ts. Generate a component called AiRecommendations that checks useFeatureFlag('ai_recommendations') at the top and returns null if the flag is false. If true, render a section with heading 'Recommended for you' and a grid of 4 placeholder product cards.

Cursor Prompt

In Cursor Chat (Cmd+L), type: 'Using @file src/utils/featureFlags.ts, generate src/components/AiRecommendations.tsx. At the top call useFeatureFlag("ai_recommendations"). If false, return null. If true, render a section with heading "Recommended for you" and a 4-column grid of ProductCard components. Named export. Strict TypeScript.'

Frequently asked questions

Can Cursor work with LaunchDarkly's React SDK instead of a custom hook?

Yes. Add 'Import useFlags from launchdarkly-react-client-sdk and destructure the specific flag: const { ai_recommendations } = useFlags()' to .cursorrules. Cursor will use the LaunchDarkly pattern wherever it generates flag-gated components.

How do I get Cursor to clean up a flag that is being permanently enabled?

Use Composer (Cmd+I) in Agent mode: 'Find all usages of useFeatureFlag("old_feature_flag") across the codebase. Remove the flag check and always render/execute the truthy branch. Delete the falsy branch code.' Review the diff carefully before accepting.

Can I gate a back-end service method with a flag, not just a route?

Yes. Include 'In service classes, call isFeatureEnabled("FLAG_NAME") at the top of any method that implements a flagged feature. Throw a FeatureNotAvailableError if the flag is false.' in your .cursorrules and your Chat prompt.

What if my flag names change between environments?

If the flag names are the same across environments (only the values differ, controlled by your flag service), you do not need environment-specific .cursorrules. If the names themselves differ, use environment variable references in .cursorrules: 'Flag names are read from FEATURE_FLAGS_* environment variables.'

Does Cursor respect the flag check if I regenerate a component in a later Chat session?

Only if the flag check is in .cursorrules. If you rely solely on the @file reference from a previous session, a fresh session without that context may regenerate the component without the flag. Always keep the flag pattern in .cursorrules for persistence.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.