SDKs
OpenFeature
An OpenFeature provider for the JavaScript server SDK (
@openfeature/server-sdk) and web SDK (@openfeature/web-sdk). It wraps a NanoFlags client: evaluation stays local and synchronous inside the provider, and the NanoFlags client keeps doing the loading, live updates and polling.On this page
Install
npm install @nanoflags/openfeature-provider @nanoflags/sdk @openfeature/server-sdk # or @openfeature/web-sdkServer
import { OpenFeature } from "@openfeature/server-sdk";
import { createClient } from "@nanoflags/sdk";
import { NanoFlagsProvider } from "@nanoflags/openfeature-provider/server";
const nanoflags = createClient({ sdkKey: process.env.NANOFLAGS_SDK_KEY!, baseUrl: "https://edge.nanoflags.io", service: "checkout-api" });
await OpenFeature.setProviderAndWait(new NanoFlagsProvider({ client: nanoflags }));
const client = OpenFeature.getClient();
const enabled = await client.getBooleanValue("checkout-v2", false, { targetingKey: user.id, signedIn: true, region: "US" });Web
import { OpenFeature } from "@openfeature/web-sdk";
import { createClient } from "@nanoflags/sdk";
import { NanoFlagsWebProvider } from "@nanoflags/openfeature-provider/web";
const nanoflags = createClient({ sdkKey: "nf_pub_…", baseUrl: "https://edge.nanoflags.io" });
await OpenFeature.setContext({ targetingKey: user.id, plan: user.plan });
await OpenFeature.setProviderAndWait(new NanoFlagsWebProvider({ client: nanoflags }));
const ranking = OpenFeature.getClient().getStringValue("search-ranking", "relevance-v2");Options
| Option | Default | Description |
|---|---|---|
client | required | A @nanoflags/sdk client. |
closeClient | false | Close the NanoFlags client when the provider shuts down. |
evaluator | the client | Function returning an object with evaluate; redirects evaluations, for example to the current request's test session. |
import { flagsFor } from "@nanoflags/sdk/node";
new NanoFlagsProvider({ client: nanoflags, evaluator: () => flagsFor(nanoflags) });What is supported
| OpenFeature | NanoFlags |
|---|---|
resolveBoolean/String/Number/ObjectEvaluation | boolean, string, number, json flags. Object resolution accepts any JSON value (a json flag may hold a string or a number). |
targetingKey | Context attribute key, the identity used for rollout bucketing. It overrides an attribute named key. |
| Other context attributes | Passed through. Date values become ISO strings. Non-finite numbers and undefined are dropped. |
reason | TARGETING_MATCH (a fixed-value rule matched) · SPLIT (a rollout rule matched, in or out of the allocation) · DEFAULT (no rule matched) · DISABLED (flag off, off value served) · ERROR. |
variant | The id of the matching rule, when a rule matched. Otherwise absent. |
flagMetadata | { revision }: the revision the value came from. |
| Errors (default value returned, reason ERROR) | FLAG_NOT_FOUND (unknown, archived, or not client-exposed with a client key) · TYPE_MISMATCH · GENERAL (malformed configuration) · PROVIDER_NOT_READY (nothing loaded yet). |
| Provider status and events | READY when a current bundle is in use · STALE when the bundle is not known to be current (evaluations continue) · ERROR when initialization ends without any configuration (READY follows once one arrives) · CONFIGURATION_CHANGED for every new revision, with metadata.revision. |
| Web SDK context changes | Evaluation is local, so a new context applies to the next evaluation without a network round trip. |
| Hooks, domains, context merging, evaluation details | Provided by the OpenFeature SDK and unaffected. |
What is not supported
- Named variants. Rules serve values, not named variants;
variantcarries the rule id and is absent forDEFAULTandDISABLED. flagsChangedonCONFIGURATION_CHANGED: the event says that a new revision is in use, not which flags differ.- Tracking (
track) is not implemented. NanoFlags' own sampled telemetry is configured on the SDK client. - Provider hooks,
PROVIDER_FATALandRECONCILINGare not emitted. A revoked or wrong key surfaces asERROR(no configuration) orSTALE(a configuration was already loaded). - Reasons
STATIC,CACHEDandTARGETING_KEY_MISSINGare not used. A rollout evaluated without a targeting key is treated as outside the allocation and reported asSPLIT. - Other languages: this page covers the JavaScript/TypeScript provider. Python and Go have their own providers (Python, Go); every other language can use an OFREP provider.
STALEandERRORdescribe the client's configuration, not individual flags; a flag evaluated whileSTALEreports its normal reason.
The provider is tested through the real OpenFeature SDKs for the surface listed above. This is not a claim of conformance beyond that surface.