Node.js SDK
@feathq/js-sdk is the server-side SDK for Node.js, Bun, and Deno. It fetches a per-environment datafile and evaluates flags locally.
Install
Section titled “Install”npm install @feathq/js-sdk# oryarn add @feathq/js-sdkNode.js 18 or newer (uses built-in fetch). Bun and Deno also work.
For browser code use @feathq/web-sdk.
import { FeatClient } from "@feathq/js-sdk";
const client = new FeatClient({ apiKey: process.env.FEAT_SERVER_KEY!, // feat_sdk_… dataPlaneUrl: "https://data.feat.so",});
await client.ready();
const result = await client.evaluate("checkout-v2", false, { targetingKey: "user-123", user: { plan: "pro", email: "alice@example.com" },});
if (result.value) { // …}Use a server API key (feat_sdk_…).
const enabled = await client.getBooleanValue(key, defaultValue, context);const variant = await client.getStringValue(key, defaultValue, context);const limit = await client.getNumberValue(key, defaultValue, context);const config = await client.getObjectValue(key, defaultValue, context);
const detailed = await client.evaluate(key, defaultValue, context);// detailed.value, detailed.variationId, detailed.reason, detailed.errorMessageThe shape of context is documented in Contexts.
reason is one of TARGETING_MATCH, SPLIT, FALLTHROUGH, DEFAULT, DISABLED, or ERROR. See Evaluation order for what each one means.
Configuration
Section titled “Configuration”new FeatClient({ apiKey: process.env.FEAT_SERVER_KEY!, dataPlaneUrl: "https://data.feat.so", pollInterval: 30_000, // ms; default 30000, minimum 5000 bootstrap: serializedDatafile, // optional: skip the initial fetch});dataPlaneUrl must be https:// in production. Plaintext is rejected except for http://localhost during tests.
Lifecycle
Section titled “Lifecycle”client.ready()resolves once the first datafile is loaded. Call evaluations only after.- The SDK polls in the background. New datafiles replace the in-memory copy atomically.
- The SDK keeps a
socketopen for nothing; it is pure HTTP polling. - Call
await client.close()on shutdown to stop the poller and drain in-flight requests.
OpenFeature
Section titled “OpenFeature”import { OpenFeature } from "@openfeature/server-sdk";import { FeatClient, FeatProvider } from "@feathq/js-sdk";
const featClient = new FeatClient({ apiKey, dataPlaneUrl });await OpenFeature.setProviderAndWait(new FeatProvider(featClient));
const client = OpenFeature.getClient();const enabled = await client.getBooleanValue("checkout-v2", false, { targetingKey: "user-123",});See OpenFeature for more on the standard.
Related
Section titled “Related”- Datafile format for the wire shape.
- Contexts for the evaluation input.
- Evaluation order for the decision chain.