Skip to content

Basic Usage

Learn how to check flags, handle defaults, and integrate feature flags into your application.

Checking a Flag

The most common operation is checking if a flag is enabled:

import { Featsync } from '@featsync/sdk';
const featsync = new Featsync({
apiKey: 'fs_your_api_key',
});
// Check if a flag is enabled
if (await featsync.isEnabled('new-feature')) {
showNewFeature();
} else {
showOldFeature();
}

Default Values

If a flag doesn’t exist or there’s an error, isEnabled returns false by default. You can specify a different default:

// Returns true if flag doesn't exist
const enabled = await featsync.isEnabled('beta-feature', true);

Getting Flag Details

For more information about a flag, use getFlag:

const flag = await featsync.getFlag('gradual-rollout');
console.log(flag.key); // 'gradual-rollout'
console.log(flag.enabled); // true
console.log(flag.percentage); // 50 (for percentage flags) or null

Getting All Flags

Fetch all flags in a single API call:

const flags = await featsync.getAllFlags();
if (flags['feature-a']?.enabled) {
// Feature A is on
}
if (flags['feature-b']?.enabled) {
// Feature B is on
}

This is useful when you need to check multiple flags and want to minimize API calls.

Conditional Rendering

Use flags to conditionally render UI:

async function renderNavigation() {
const showNewNav = await featsync.isEnabled('new-navigation');
return showNewNav ? <NewNavigation /> : <OldNavigation />;
}

Feature Variations

Use flags to switch between different implementations:

async function getPaymentProcessor() {
if (await featsync.isEnabled('use-stripe')) {
return new StripeProcessor();
}
return new PayPalProcessor();
}

Error Handling

The SDK is designed to be resilient. It won’t throw errors during normal operation:

// This won't throw even if the API is down
const enabled = await featsync.isEnabled('my-flag');
// Returns false (or your default) on error

For explicit error handling:

try {
const flags = await featsync.getAllFlags();
} catch (error) {
console.error('Failed to fetch flags:', error);
// Use fallback logic
}

Clearing the Cache

Force fresh data on the next flag check:

featsync.clearCache();
// Next call will fetch from API
const enabled = await featsync.isEnabled('my-flag');

Switching Environments

Change environments at runtime:

// Switch to staging
featsync.setEnvironment('staging');
featsync.clearCache();
// Flags will now be fetched from staging

Best Practices

1. Initialize Once

Create a single SDK instance and reuse it:

lib/featsync.js
export const featsync = new Featsync({
apiKey: process.env.FEATSYNC_API_KEY,
});

2. Use Meaningful Flag Names

// Good
'new-checkout-flow';
'enable-dark-mode';
'show-beta-banner';
// Bad
'flag1';
'test';
'temp';

3. Have a Fallback

Always consider what happens when the flag is off:

if (await featsync.isEnabled('experimental-search')) {
return experimentalSearch(query);
}
// Don't forget the else case!
return standardSearch(query);

4. Clean Up Old Flags

Once a feature is fully rolled out, remove the flag check from your code:

// Before: Flag check
if (await featsync.isEnabled('new-checkout')) {
return <NewCheckout />;
}
return <OldCheckout />;
// After: Flag removed, feature is default
return <NewCheckout />;

Next Steps