Skip to content

TypeScript Server SDK

The FlagshipServerProvider implements the OpenFeature server provider interface. The provider works in Cloudflare Workers, Node.js, and any server-side JavaScript runtime that supports the Fetch API.

Inside a Cloudflare Worker, you can pass the Flagship binding directly to the provider. This avoids HTTP overhead and is the recommended approach. Outside of Workers, initialize the provider with an app ID and account ID.

Setup

Pass the Flagship binding directly to the provider. This is the recommended approach inside a Worker.

JavaScript
import { OpenFeature } from "@openfeature/server-sdk";
import { FlagshipServerProvider } from "@cloudflare/flagship/server";
export default {
async fetch(request, env) {
await OpenFeature.setProviderAndWait(
new FlagshipServerProvider({ binding: env.FLAGS }),
);
const client = OpenFeature.getClient();
const showNewCheckout = await client.getBooleanValue(
"new-checkout",
false,
{ targetingKey: "user-42", plan: "enterprise" },
);
if (showNewCheckout) {
return new Response("New checkout enabled!");
}
return new Response("Standard checkout.");
},
};

Configuration options

OptionTypeRequiredDescription
bindingFlagshipNoThe Flagship binding from env.FLAGS. Use this inside a Worker for best performance. The binding handles authentication automatically.
appIdstringNoThe Flagship app ID from the Cloudflare dashboard. Required when not using a binding.
accountIdstringNoYour Cloudflare account ID. Required when using appId.
authTokenstringNoA Cloudflare API token with Flagship read permissions. Required when not using a binding.
fetchOptionsRequestInitNoCustom fetch options applied to HTTP requests.
timeoutnumberNoRequest timeout in milliseconds. Defaults to 5000.
retriesnumberNoRetry attempts on transient errors. Defaults to 1 and is capped at 10.
retryDelaynumberNoDelay between retries in milliseconds. Defaults to 1000 and is capped at 30000.
cacheTtlnumberNoCache TTL in milliseconds. Enables response caching when greater than 0.
cacheMaxSizenumberNoMaximum cached entries. Defaults to 1000 when cacheTtl is set.

Provide either binding or appId, accountId, and authToken.

Response caching

Server-side response caching is off by default. Enable it with cacheTtl when you want repeated evaluations for the same flag, type, and evaluation context to reuse a recent result.

TypeScript
new FlagshipServerProvider({
appId: "<APP_ID>",
accountId: "<ACCOUNT_ID>",
authToken: "<API_TOKEN>",
cacheTtl: 30_000,
cacheMaxSize: 1000,
});

Use caching for high-traffic server applications that repeatedly evaluate the same flags for the same contexts. Cached values may be stale until the TTL expires, so keep the TTL short for flags that you expect to change during active rollouts. The provider does not cache disabled flags or errors.

Evaluation context

OpenFeature uses an evaluation context to pass user attributes to the flag provider. The targetingKey field is the primary user identifier.

Pass additional attributes alongside targetingKey to match targeting rules. For example, you can include plan, country, or any custom attribute your rules reference.

Use primitive context values such as strings, numbers, booleans, and Date objects. The provider rejects objects and arrays as invalid context.

JavaScript
const value = await client.getBooleanValue("new-checkout", false, {
targetingKey: "user-42",
plan: "enterprise",
country: "US",
});

Available hooks

The SDK ships with two hooks that you can attach to the OpenFeature client.

  • LoggingHook — Logs structured information for every evaluation.
  • TelemetryHook — Captures timing and event data for observability.
JavaScript
import { LoggingHook, TelemetryHook } from "@cloudflare/flagship/server";
OpenFeature.addHooks(new LoggingHook(), new TelemetryHook());

Migrate from another provider

If you use another OpenFeature-compatible provider (for example, LaunchDarkly or Flagsmith), switch to Flagship by replacing the provider initialization. No changes are needed at evaluation call sites.

JavaScript
// Before
await OpenFeature.setProviderAndWait(
new LaunchDarklyProvider({ sdkKey: "..." }),
);
// After
await OpenFeature.setProviderAndWait(
new FlagshipServerProvider({
appId: "<APP_ID>",
accountId: "<ACCOUNT_ID>",
authToken: "<API_TOKEN>",
}),
);