npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unleash/openfeature-node-provider

v1.0.0

Published

OpenFeature provider for the Unleash Node.js server-side SDK

Readme

Unleash OpenFeature Provider for Node.js

An OpenFeature provider backed by the official Unleash Node.js SDK (unleash-client), for server-side Node.js applications.

Adheres to OpenFeature specification v0.8.0 via @openfeature/server-sdk >=1.14.0 (the first release of the server SDK implementing spec v0.8.0). All required provider behavior is implemented: typed flag resolution, evaluation context handling, lifecycle (initialization/shutdown), and provider events. Of the spec's optional capabilities, provider hooks and the tracking API (spec section 6) are not implemented — see Out of scope.

The provider constructs and owns the Unleash client: it is created and started when the provider is initialized, and destroyed (with a final metrics flush) when OpenFeature shuts down. Flags are evaluated locally by the Unleash SDK against the translated evaluation context, so Unleash usage metrics keep working as usual.

Installation

npm install @unleash/openfeature-node-provider @openfeature/server-sdk unleash-client

If you cloned without submodules, initialize the verifier harness:

git submodule update --init --recursive

The contract tests use the verifier submodule. To refresh it:

git submodule update --remote --merge verifier

Usage

import { OpenFeature } from '@openfeature/server-sdk';
import { UnleashProvider } from '@unleash/openfeature-node-provider';

const provider = new UnleashProvider({
  // any UnleashConfig accepted by the Unleash Node SDK
  url: 'https://app.unleash-hosted.com/demo/api/',
  appName: 'my-app',
  customHeaders: { Authorization: '<your-api-token>' },
});

// Resolves once the Unleash client is ready and synchronized
await OpenFeature.setProviderAndWait(provider);

const client = OpenFeature.getClient();

const enabled = await client.getBooleanValue('my-flag', false, { targetingKey: 'user-123' });
const variantText = await client.getStringValue('my-copy-experiment', 'default text', {
  targetingKey: 'user-123',
  sessionId: 'session-1',
  region: 'EMEA', // custom keys become Unleash properties
});

The underlying Unleash client is available as an escape hatch via provider.unleashClient.

Concept mapping

Flag evaluation

| OpenFeature call | Unleash mechanism | | --- | --- | | getBooleanValue / getBooleanDetails | isEnabled() | | getStringValue / getStringDetails | variant payload of type string or csv | | getNumberValue / getNumberDetails | variant payload of type number | | getObjectValue / getObjectDetails | variant payload of type json (parsed) |

If the variant payload type does not match the requested type, the evaluation returns the default value with errorCode: TYPE_MISMATCH. A flag that does not exist in Unleash returns the default value with errorCode: FLAG_NOT_FOUND (note that this differs from the raw Unleash SDK, which treats unknown flags as disabled). Disabled flags resolve variant evaluations to the default value with reason DISABLED; enabled flags without an assigned variant (or without a payload) resolve to the default value with reason DEFAULT.

The assigned variant name is reported in variant, and flagMetadata carries featureEnabled and payloadType.

Evaluation context

| OpenFeature context key | Unleash context field | | --- | --- | | targetingKey | userId (takes precedence over an explicit userId key) | | userId, sessionId, remoteAddress, environment, appName | same field | | currentTime (Date or ISO string) | currentTime | | any other key | properties.<key> |

Strings and numbers pass into properties unchanged; booleans and dates are stringified. Nested objects and arrays are dropped (with a debug log), since Unleash constraints cannot evaluate them.

Stickiness

Unleash resolves default stickiness for gradual rollouts and variant assignment internally, falling back through userIdsessionId → random. The provider does not replicate or alter this chain — it only fills in the fields. targetingKey fills userId; if you want session-based stickiness, set sessionId in the evaluation context. A missing targetingKey is never an error: evaluation falls through Unleash's normal chain and ends at random stickiness. Custom stickiness on a custom context field works via properties.

Events and lifecycle

| Unleash client state | OpenFeature provider event | | --- | --- | | ready + synchronized | PROVIDER_READY | | configuration changed | PROVIDER_CONFIGURATION_CHANGED | | fetch error while cached flags are served | PROVIDER_STALE | | error before any flag data is available | PROVIDER_ERROR | | recovery after an error | PROVIDER_READY |

initialize() rejects on the first Unleash error instead of waiting forever, so setProviderAndWait() cannot hang on a misconfigured connection. The Unleash client keeps retrying in the background and the provider recovers (emitting PROVIDER_READY) once a fetch succeeds.

Reasons

Unleash does not expose which strategy matched an evaluation, so reasons are best-effort: TARGETING_MATCH for enabled flags, DISABLED for disabled ones, SPLIT for assigned variants, DEFAULT when the default value is used, and ERROR alongside an error code.

Out of scope

The OpenFeature tracking API is not implemented. Unleash impression data and usage metrics are unaffected — they are handled by the underlying SDK.

Development

npm install
npm test        # vitest: unit + offline integration tests (bootstrap data, no server)
npm run build   # tsup: ESM + CJS + type declarations

License

Apache-2.0