@flagsync/js-sdk is an isomorphic library capable of running on Node.js and web browsers. However, it is meant for single-user contexts in browser environments, such as mobile or desktop web applications.
Compatible with Node.js 16+ and ES5.
TypeScript is fully supported.
Note on Node.js
While this SDK is stable in Node.js 16+, this is to support uncommon, one-off cases where you may need to initialize feature flags for a single user server-side.
For server-side applications, including SSR web applications, we strongly recommend using the Node.js SDK.
Get your SDK key
To start, you'll first need to locate your SDK key, which is specific to an Environment (e.g. Test, Production, Staging, etc.)
Your API requests are authenticated using SDK keys. Any request that doesn't include an SDK key will return an error.
Client-side SDK keys are safe to expose, and should be used for client-facing applications such as Web Browsers, whereas server-side SDKs can expose details of your flag rules, such as internal email addresses or user keys, and should never be made public.
Install the library
To connect to FlagSync from code, you'll need to install the SDK.
Once instantiated, there are two ways to observe the readiness of the SDK: events and promises.
Events
client.once(client.Event.SDK_READY, () => {// SDK is readyconstvalue=client.flag<string>('my-flag')});client.once(client.Event.SDK_READY_FROM_STORE, () => {// Emitted once the SDK has loaded flags from LocalStorage.// Fires quickly since no network request is required.// This data may be stale, and should not be considered a // replacement for the SDK_READY event.constvalue=client.flag<string>('my-flag')});
The SDK_READY_FROM_STORE event is useful for quickly loading flags from LocalStorage in Web browser environments.
This event only fires when using the localstorage storage type; the default is memory.
Promises & async/await
The SDK has two methods that return a promise for initialization, waitForReady and waitForReadyCanThrow. The former is identical to the SDK_READY event.
client.waitForReady().then(() => {// SDK is readyconstvalue=client.flag<string>('my-flag') })// Or with awaitawaitclient.waitForReady();constvalue=client.flag<string>('my-flag')
The other method, waitForReadyCanThrow, will throw an error if the SDK fails to initialize. This may be helpful in certain situations.
All client-facing errors are normalized to FsServiceError in the SDK.
client.waitForReadyCanThrow().then(() => {// SDK is readyconstvalue=client.flag<string>('my-flag') }).catch(e => {// Initialization failedconsterror= e asFsServiceError; });// Or with awaittry {awaitclient.waitForReadyCanThrow();constvalue=client.flag<string>('my-flag')} catch (e) {// Initialization failedconsterror= e asFsServiceError;}
Flag evaluation
The flag method retrieves the value of a feature flag identified by the flagKey.
This function evaluates the user context against individual targeting rules, percentage rollouts, and default variants to determine and return the appropriate feature flag variant for that specific user.
If the SDK is not ready, the method will return the default value, or control if one is not provided.
When you call the track function to submit events, you can optionally provide key-value properties or a numeric eventValue.
We'll discuss the differences below, and when you might choose one over the other.
Example (Page Load Time)
Say you're releasing a new feature and want to ensure page load times have not degraded. Or, you're testing some optimizations and want to validate that they've had a positive effect.
We'll use the eventValue for this type of event.
First, you'll start by submitting an Event.
client.track('page_load_time',1.42);
Later on, you may create a Metric called "Average Page Load Time" from the page_load_time event to harvest the values.
Finally, you may link this metric with a feature flag in an Experiment to prove your hypothesis.
Learn about Metrics to see how they work alongside events.
Example (Purchase Events)
Say you're releasing a feature that you believe will increase the purchase amounts of your customers. Or, you're testing different discount amounts that you believe will increase the overall number of purchases.
You'll most likely want to track purchase events within your application along with the item purchased.
Later on, you may create a Metric called "Average Purchase Price per User" to harvest the price of items submitted with the purchase_event.
Or, you may create a Metric called "Count of Discounts" to track the discount value.
Finally, you may link these metrics with a feature flag in an Experiment to prove your hypothesis.
Learn about Metrics to see how they work alongside events.
Flag updates
When a change to a feature flag is made in the FlagSync dashboard, a server-side event (SSE) is sent from FlagSync servers to the SDK.
Value change propagation is on the order of milliseconds.
While the default synchronization method is SSE, you may opt to use polling instead, or disable synchronization entirely. You can control this with sync option:
When initializing the factory, you can pass custom attributes about the user or user segment, which are automatically made available in the FlagSync Dashboard for individual targeting.
By default, flags are stored in memory, however when running in a Web Browser, you can opt to use LocalStorage instead, which is useful for quickly loading the last state of your flags.
Emitted once the SDK has loaded flags from LocalStorage.
Fires quickly since no network request is required.
This data may be stale, and should not be considered a replacement for the SDK_READY event.
FsConfig
You can configure any of the following option arguments when initializing the FlagSyncFactory.
typeFsFlagValue=any;exporttypeFsFlagSet=Record<string,FsFlagValue>;typeCustomAttributeValue=any;typeCustomAttributes=Record<string,CustomAttributeValue>;typeStorageType='memory'|'localstorage';typeSyncType='stream'|'poll'|'off';exportinterfaceFsConfig {/** * The SDK key for the FlagSync project. */readonly sdkKey:string;readonly core: {/** * The unique key for the user, or organization. */ key:string;/** * The custom attributes for the user, or organization, which are * made available for rule targeting in your FlagSync dashboard. * > CustomAttributes: Record<string, CustomAttributeValue> * Example: * { * "email": "user@example.com" * "jobTitle: "QA" * "location": "Boston * } */ attributes?:CustomAttributes; };/** * Initialize the SDK with a set of flags. * > FsFlagSet: Record<string, FsFlagValue>; */readonly bootstrap?:FsFlagSet;/** * The storage configuration for the SDK. * > StorageType: 'memory' | 'localstorage' */readonly storage?: { type?:StorageType; prefix?:string; };/** * The configuration for the SDK's sync mechanism. * > SyncType: 'stream' | 'poll' | 'off'; */readonly sync?: { type?:SyncType; pollRate?:number; };readonly tracking?: { impressions?: { maxQueueSize:number; pushRate:number; }; events?: { maxQueueSize:number; pushRate:number; }; };/** * The configuration for the SDK's logging. * > LogLevel: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'NONE'; */readonly logLevel?:LogLevel;}