@featureflare/sdk-js
v0.0.122
Published
JavaScript/TypeScript SDK for FeatureFlare feature flags.
Readme
@featureflare/sdk-js
JavaScript/TypeScript SDK for FeatureFlare feature flags.
Installation
npm install @featureflare/sdk-js
# or
pnpm add @featureflare/sdk-js
# or
yarn add @featureflare/sdk-jsUsage
Basic Example
import { FeatureFlareClient } from '@featureflare/sdk-js';
// SDK automatically uses production API URL
// Set FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY env var, or pass sdkKey explicitly
const featureflare = new FeatureFlareClient({
sdkKey: 'your-sdk-key-here'
});
const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);
console.log(enabled);
const detailed = await featureflare.evaluate('new-nav', { id: 'user-123' }, false);
console.log(detailed.value, detailed.metadata.reason, detailed.metadata.source);Environment Variables
The SDK automatically reads from environment variables if sdkKey is not provided:
FEATUREFLARE_CLIENT_KEY- Client SDK key (for browser/mobile)FEATUREFLARE_SERVER_KEY- Server SDK key (for backend)FEATUREFLARE_ENV_KEY- Expected environment key binding (development,staging,production, etc.)
// In Node.js, this will use FEATUREFLARE_CLIENT_KEY or FEATUREFLARE_SERVER_KEY from env
const featureflare = new FeatureFlareClient();Resilience options (cache/retry/timeout/bootstrap)
const featureflare = new FeatureFlareClient({
sdkKey: 'featureflare_cli_...',
timeoutMs: 3000,
maxRetries: 2,
backoffMs: 200,
jitter: 0.25,
cacheTtlMs: 60_000,
staleTtlMs: 10_000,
bootstrap: {
flags: { 'new-nav': true },
killSwitches: ['dangerous-flow']
},
realtime: {
// optional: enabled defaults to true (SSE primary, polling fallback)
// optional: hidden tabs disconnect by default and reconnect on visibility restore
pollingIntervalMs: 15_000,
ssePath: '/api/v1/sdk/stream'
}
});- Cache-first evaluation order: fresh cache → stale cache (+ async revalidate) → bootstrap/persistent cache → default.
bool(...)andevaluate(...)are outage-safe and return deterministic defaults for expected network failures.- Hard kill switches have highest precedence and return
falseeven when the API is unreachable. - Realtime updates are enabled by default: SSE is primary transport; polling is used automatically as fallback when SSE is unavailable.
- In browser runtimes, hidden tabs disconnect the realtime stream by default and reconnect with a fresh authenticated stream request when the tab becomes visible again.
To explicitly disable realtime updates:
const featureflare = new FeatureFlareClient({
sdkKey: 'featureflare_cli_...',
realtime: { enabled: false }
});API Base URL
The SDK automatically determines the API base URL:
options.apiBaseUrl: Highest priority if provided.- Environment variables:
FEATUREFLARE_API_BASE_URL, thenSHIPIT_API_BASE_URL. - Default fallback (all runtimes):
https://api.featureflare.com.
Example override:
const featureflare = new FeatureFlareClient({
apiBaseUrl: 'https://flags.your-company.com',
sdkKey: 'featureflare_cli_...'
});User Payload
import { FeatureFlareClient, type FeatureFlareUserPayload } from '@featureflare/sdk-js';
const user: FeatureFlareUserPayload = {
id: 'user-123', // Required: unique user identifier
email: '[email protected]',
name: 'John Doe',
country: 'US',
meta: { // Custom attributes for targeting
companyId: 'acme',
plan: 'pro'
}
};
const enabled = await featureflare.bool('feature-flag', user, false);API Reference
FeatureFlareClient
Constructor
new FeatureFlareClient(options?: FeatureFlareClientOptions)Options:
apiBaseUrl?: string- Explicit FeatureFlare API base URL.sdkKey?: string- SDK key (client or server). If not provided, reads fromFEATUREFLARE_CLIENT_KEYorFEATUREFLARE_SERVER_KEYenv vars.projectKey?: string- Legacy: project key (requiresenvKey). Not recommended.envKey?: string- Environment key (default:'production'). Only used withprojectKey.
When using sdkKey, envKey is sent as an expected environment binding. The API rejects requests if the key's actual environment does not match envKey.
Methods
bool(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<boolean>
Evaluates a boolean feature flag for a user.
flagKey: The flag key to evaluateuser: User payload withidorkey(required)defaultValue: Default value if evaluation fails (default:false)
Returns Promise<boolean> - The flag value for the user.
evaluate(flagKey: string, user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<{ value: boolean; metadata: ... }>
Evaluates a flag with diagnostics metadata:
reason:fresh_cache | stale_cache | bootstrap | default | network | kill_switchisStalelatencyMssource,updatedAt,staleAt,expiresAt
Example:
const enabled = await featureflare.bool('new-nav', { id: 'user-123' }, false);flags(user: FeatureFlareUserPayload, defaultValue?: boolean): Promise<Record<string, boolean>>
Fetches all boolean flags for the provided user.
user: User payload withidorkey(required)defaultValue: Default value to apply for missing/offline evaluations (default:false)
Returns Promise<Record<string, boolean>> - A map of flagKey -> value.
Example:
const allFlags = await featureflare.flags({ id: 'user-123' }, false);Error Handling
bool(...) and evaluate(...) are non-throwing for expected outage/network states. If the API request fails, the SDK falls back to stale/bootstrap/persistent/default values deterministically.
const enabled = await featureflare.bool('flag', user, false);SDK Keys
Each environment has two SDK keys:
- Server key: Secret. Use only in trusted server environments.
- Client key: Not a secret. Intended for browser/mobile SDKs.
Get your SDK keys from your FeatureFlare Console → Environments.
Security: Client-side flags are not authorization
Client keys can be extracted from your frontend bundle. Never gate truly sensitive operations solely with client-evaluated flags—enforce authorization on your backend. Use client keys for non-sensitive UI toggles (e.g. feature visibility, A/B tests). For access control, billing gates, or data protection, always validate on the server.
License
MIT
