Flag Detection
How FlagShark automatically detects feature flags in your code using advanced parsing techniques.
FlagShark uses sophisticated code analysis to detect feature flags across your codebase. Unlike simple text search, FlagShark understands your code's syntax and accurately identifies flag usage patterns.
How Detection Works
FlagShark operates in two phases:
- PR Preview: When you open a pull request, FlagShark analyzes the diff and posts a comment showing which flags are being added or removed
- Lifecycle Tracking: When code reaches your default branch (via merge OR direct push), flags are persisted to your inventory
PR Analysis
When you open a pull request, FlagShark:
Real-time Lifecycle Tracking
Beyond PR analysis, FlagShark monitors your default branch for all flag changes in real-time:
- Merged PRs: When a PR is merged, the push event triggers flag lifecycle tracking
- Direct commits: Commits pushed directly to main/master are also tracked
- Hotfixes: Emergency fixes that bypass the PR workflow are still captured
This ensures your flag inventory reflects what's actually in production, regardless of how code got there.
Tree-Sitter Parsing
FlagShark uses tree-sitter, the same parsing technology used by GitHub and modern code editors. This provides:
Accurate Detection
Tree-sitter builds a complete syntax tree of your code, allowing FlagShark to distinguish between:
// ✅ Detected: Actual flag usage
const enabled = ldClient.variation('my-flag', user, false);
// ✅ Detected: Different SDK patterns
const { myFlag } = useFlags();
if (featureFlags.isEnabled('my-flag')) { }
// ❌ Not detected: Just a string (not a flag call)
const flagName = 'my-flag'; // This alone isn't detected
// ❌ Not detected: Comments
// ldClient.variation('commented-out-flag', user, false);
Language-Aware
Tree-sitter understands language-specific syntax:
// TypeScript: Handles type annotations
const enabled: boolean = ldClient.variation<boolean>('my-flag', user, false);
// JavaScript: Handles both CommonJS and ES modules
const { variation } = require('launchdarkly-node-client-sdk');
import { useLDClient } from 'launchdarkly-react-client-sdk';
Performance
Tree-sitter is extremely fast - FlagShark can parse thousands of lines of code in milliseconds, ensuring your PR checks complete quickly.
What FlagShark Detects
For each detected flag, FlagShark captures:
| Field | Description | Example |
|---|---|---|
| Flag key | The string identifier | enable-dark-mode |
| File path | Where the flag is used | src/components/Theme.tsx |
| Line number | Exact location | Line 42 |
| SDK method | How the flag is called | variation |
| Operation | Added, removed, or modified | Added |
| Default value | Fallback when flag unavailable | false |

Detection in Action
Adding a New Flag
When you add a new feature flag in a PR:
// src/features/checkout/PaymentForm.tsx (line 23)
const useNewPaymentFlow = ldClient.variation('enable-new-payment-flow', user, false);
FlagShark detects:
- Flag:
enable-new-payment-flow - File:
src/features/checkout/PaymentForm.tsx - Line: 23
- Operation: Added
- Default:
false
Removing a Flag
When you remove flag code:
- const useNewPaymentFlow = ldClient.variation('enable-new-payment-flow', user, false);
- if (useNewPaymentFlow) {
- return <NewPaymentForm />;
- }
return <PaymentForm />;
FlagShark detects the removal and marks the flag as cleaned up in your dashboard.
Modifying Flag Usage
When you change how a flag is used:
- const enabled = ldClient.variation('my-flag', user, false);
+ const enabled = ldClient.variation('my-flag', user, true); // Changed default
FlagShark detects the modification and updates the metadata.
Supported SDK Patterns
FlagShark recognizes common SDK patterns out of the box:
LaunchDarkly
// Client-side
ldClient.variation('flag-key', defaultValue);
ldClient.boolVariation('flag-key', defaultValue);
ldClient.stringVariation('flag-key', defaultValue);
// React
const { flagKey } = useFlags();
const flags = useLDClient();
// Server-side
client.variation('flag-key', context, defaultValue);
Unleash
// JavaScript/TypeScript
unleash.isEnabled('flag-key');
unleash.getVariant('flag-key');
// React
const enabled = useFlag('flag-key');
const variant = useVariant('flag-key');
Split
// JavaScript
client.getTreatment('flag-key');
client.getTreatments(['flag-1', 'flag-2']);
Custom Patterns
You can configure custom detection patterns in .flagshark.yaml:
providers:
- name: "Custom Feature Flags"
methods:
- name: "isFeatureEnabled"
flag_key_index: 0
- name: "getFeatureVariant"
flag_key_index: 0
See Configuration for details.
Detection Accuracy
True Positives
FlagShark accurately detects:
- Standard SDK method calls
- Aliased imports
- Destructured flag access
- Async flag evaluation
- Flags in any file location (not just specific directories)
What's Not Detected
FlagShark intentionally doesn't detect:
- Commented code: Flags in comments are ignored
- String literals alone: Just having
'my-flag'as a string isn't a flag usage - Dynamic flag keys:
variation(getFlagName(), ...)can't determine the flag name - Unsupported SDKs: SDKs not in your configuration
Diff-Based Detection
FlagShark analyzes PR diffs, not entire files. This means:
Advantages
- Fast: Only processes changed code
- Focused: Shows what's new in this PR
- Accurate: Tracks additions vs. removals
Considerations
- Existing flags: Flags already in your codebase before FlagShark was installed aren't automatically detected
- Solution: Run a full repository scan from your dashboard to discover existing flags

Caching and Performance
FlagShark caches parsed results for performance:
- Diff caching: Same diff won't be re-parsed
- Parse tree caching: Repeated analysis is instant
- Result caching: Flag data is stored efficiently
Typical detection time: < 2 seconds for most PRs.
Debugging Detection
If flags aren't being detected:
See Flag Not Detected for detailed troubleshooting.
Related Documentation
- How Detection Works - Technical deep-dive into the detection architecture
- Supported Languages - All supported languages and SDKs
- Configuration - Custom provider setup
- GitHub Comments - How detection results appear in PRs
- Flag Not Detected - Troubleshooting detection issues