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

noibu-feature-flag

v0.2.0

Published

Noibu Feature Flag provider for web.

Readme

noibu-feature-flag

Standalone Noibu Feature Flag package for browser apps, based on OpenFeature Web SDK and GO Feature Flag web provider.

Install

npm install noibu-feature-flag

Usage

import {
  NoibuFeatureFlag,
  NoibuFeatureFlagProvider,
  NoibuProviderEvents,
  type NoibuEvaluationContext
} from "noibu-feature-flag";

const context: NoibuEvaluationContext = {
  targetingKey: "user-id",
  // Custom attributes are top-level context fields (referenced by targeting
  // rules by name, e.g. `plan`), not nested under an `attributes` key.
  plan: "pro"
};

const provider = new NoibuFeatureFlagProvider({
  endpoint: "https://your-feature-flag-endpoint/",
  apiKey: "your-api-key",
  maxRetries: 5,
  dataFlushInterval: 5 * 60 * 1000,
  apiTimeout: 1000
});

await NoibuFeatureFlag.setContext(context);
NoibuFeatureFlag.setProvider(provider);

const client = NoibuFeatureFlag.getClient("www.example.com");
client.addHandler(NoibuProviderEvents.Ready, () => {
  console.log(client.getBooleanValue("my-flag", false));
});

Automatic targeting key from the Noibu browser id

When setProvider initializes with no targetingKey in the context, the provider resolves a browser id in the background and sets it on the global context. The browser id is constant forever, resolved in priority order:

  1. live NOIBUJS.noibuBrowserID();
  2. the localStorage caches (n_browser_data from Noibu JS, or n_ff_browser_id from a previous fallback);
  3. the noibuSDKReady event, waited on for up to 1 second;
  4. failing all of those, NOIBUJS is assumed broken: a UUID is generated, persisted to n_ff_browser_id so later visits reuse it, and a warning is logged (such exposures may not join to Noibu sessions).

This never delays provider readiness; flags re-evaluate once the id arrives. An explicit targetingKey — in the initial context or set while waiting — always wins and is never overwritten.

Building the context explicitly

To guarantee the very first evaluation is already keyed to the browser id (no anonymous exposures before the id resolves), build the context up front with buildNoibuContext before registering the provider. An explicit targetingKey always wins, and if no browser id is available the context is returned unchanged.

import { buildNoibuContext, NoibuFeatureFlag } from "noibu-feature-flag";

// targetingKey defaults to NOIBUJS.noibuBrowserID() (awaits the Noibu JS SDK if needed).
// Custom attributes are top-level fields, not nested under `attributes`.
await NoibuFeatureFlag.setContext(await buildNoibuContext({ plan: "pro" }));

// ...or pass your own key (e.g. the console userId regime) — it is preserved as-is
await NoibuFeatureFlag.setContext(await buildNoibuContext({ targetingKey: "user-id" }));

Collector metadata

Every data-collector flush sends a meta object:

{
  "provider": "web",
  "openfeature": true,
  "browserId": "fb50a4f5-a785-4214-ab00-d34a15e154f5",
  "domain": "console.noibu.com",
  "sessionId": "019f6702-8298-7db2-930d-24cab496ccb6"
}

The ids are resolved lazily at collect time (each flush), not at load: domain from window.location.hostname; browserId per the priority order above; sessionId from live NOIBUJS.sessionId(), else the n_session_id localStorage cache (honoring its expiry), else null. Values passed via the exporterMetadata option always win and extra custom keys are forwarded as-is.

Scripts

  • npm run build builds ESM/CJS outputs and type declarations into dist.
  • npm run lint runs ESLint for src.