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

@fireweaveai/sdk

v2.1.0

Published

Fireweave release-engineering SDK for server runtimes: control points, target registration, release lifecycle, exposures, and health/outcome signals — with an OpenFeature provider. Runs on Node, Bun, and Deno.

Readme

@fireweaveai/sdk (Node SDK)

Fireweave release-engineering SDK for server runtimes — control points, target registration, release lifecycle, exposures, and health/outcome signals, with an OpenFeature provider for standards-compatible evaluation (spec v0.1.0).

  • Zero runtime dependencies. One peer: @openfeature/server-sdk (needed only if you use the OpenFeature provider).
  • Runs on Node ≥ 20.20, Bun ≥ 1.2, and Deno ≥ 2.0 — no Node built-ins, no Node globals (ADR-0008).
  • No vendor SDK, key, or hostname in your process. Applications hold a Fireweave project key and talk to fw-server; which backend fw-server forwards to is fw-server's concern (ADR-0005, ADR-0006).

Install

npm install @fireweaveai/sdk @openfeature/server-sdk   # or: bun add …
// Deno needs no install step
import { FireweaveClient, FireweaveRemoteAdapter, FireweaveRuntime } from 'npm:@fireweaveai/sdk';

Quick start (production path)

import { FireweaveClient, FireweaveRemoteAdapter, FireweaveRuntime } from '@fireweaveai/sdk';

// Reads FW_API_URL and FW_PROJECT_API_KEY when not passed explicitly.
const runtime = new FireweaveRuntime(new FireweaveRemoteAdapter());
const fireweave = new FireweaveClient(runtime);
await fireweave.initialize();

// Once per login: the durable facts your targeting rules match on.
await runtime.registerTarget('user_42', {
  kind: 'user',
  properties: { plan: 'pro', region: 'eu-west' },
});

// Per request.
const enabled = await fireweave.controlPoints.getBooleanValue('new-checkout', false, {
  targetingKey: 'user_42',
});

fireweave.signals.recordOutcome({ name: 'checkout', status: 'completed' });
await fireweave.shutdown();   // flushes queued exposures first

Quick start (offline, in-memory)

import { FireweaveClient, FireweaveRuntime, InMemoryAdapter } from '@fireweaveai/sdk';

const runtime = new FireweaveRuntime(new InMemoryAdapter({
  flags: { 'new-checkout': { type: 'boolean', enabled: true, value: true, variant: 'on' } },
}));
await runtime.initialize();
const fireweave = new FireweaveClient(runtime);

// → true
await fireweave.controlPoints.getBooleanValue('new-checkout', false, { targetingKey: 'u1' });

OpenFeature

import { OpenFeature } from '@openfeature/server-sdk';
import { FireweaveProvider, FireweaveRuntime, InMemoryAdapter } from '@fireweaveai/sdk';

const runtime = new FireweaveRuntime(new InMemoryAdapter({ flags: { /* … */ } }));
await OpenFeature.setProviderAndWait(new FireweaveProvider(runtime));

const enabled = await OpenFeature.getClient()
  .getBooleanValue('new-checkout', false, { targetingKey: 'user_42' });

await OpenFeature.close();

The per-call parameter is flagKey, not controlPointKey — that name is fixed by the OpenFeature specification, by spec/decision.schema.json, and by the wire protocol shared with the Python, Go, and Java SDKs. "Control point" is the product noun; flagKey is its key at those boundaries (ADR-0007).

Module layout

| Module | Responsibility | | --- | --- | | runtime.ts | Lifecycle state machine, config validation, context policy, decision construction. Evaluation never throws. | | client.ts | FireweaveClientcontrolPoints, releases, exposures, signals, guardrails (stub), capabilities. | | provider.ts | OpenFeature server provider; the only module importing @openfeature/server-sdk. | | adapters/remote.ts | FireweaveRemoteAdapter — the production backend (/v1/flags/evaluate, /v1/capture, /v1/targets/register). | | adapters/inmemory.ts | Deterministic fixture-driven adapter for tests and conformance. | | adapter.ts | The BackendAdapter boundary. Adapters never see OpenFeature types. | | context.ts | Merge order (global → client → invocation), deep copy, bounds, reserved keys. | | errors.ts | The 15-kind error taxonomy and secret redaction. | | hosts.ts | SSRF allowlist (on by default; https required off-loopback). | | env.ts | Runtime-agnostic environment read — guarded so Deno without --allow-env reports absence, not failure. |

Configuration

| Option | Env | Description | | --- | --- | --- | | apiUrl | FW_API_URL | fw-server base URL | | apiKey | FW_PROJECT_API_KEY | Fireweave project key (project-api-key_…) | | requestTimeoutMs | — | per-request deadline (default 3000) | | allowedHosts | — | SSRF allowlist override; defaults to the apiUrl host plus loopback | | — | FW_DEPRECATION_WARNINGS=1 | log one notice per process when a deprecated alias is used |


Upgrading from v2.0 to 2.1

Only one change is mandatory. If you imported the direct vendor adapter, swap it. Everything else from v2 still works, so most of this section exists to tell you what you don't have to do.

Does this affect me?

# Mandatory to fix (any hit ⇒ migration required)
rg -n "@fireweaveai/sdk/posthog|PostHogAdapter"
rg -n '"posthog-node"' package.json

# Configuration that moves
rg -n "POSTHOG_HOST|POSTHOG_API_KEY|POSTHOG_PROJECT_API_KEY"

No hits? Bump the version; you are done.

1. Swap the adapter (required)

// before
import { PostHogAdapter } from '@fireweaveai/sdk/posthog';
const adapter = new PostHogAdapter({
  projectApiKey: process.env.POSTHOG_API_KEY,
  host: process.env.POSTHOG_HOST,
  featureFlagsRequestTimeoutMs: 3000,
});

// after
import { FireweaveRemoteAdapter } from '@fireweaveai/sdk';
const adapter = new FireweaveRemoteAdapter({
  apiUrl: process.env.FW_API_URL,
  apiKey: process.env.FW_PROJECT_API_KEY,
  requestTimeoutMs: 3000,
});

| v2 option | 2.1 | | --- | --- | | projectApiKey (phc_…) | apiKey (project-api-key_…) | | host | apiUrl | | featureFlagsRequestTimeoutMs | requestTimeoutMs | | shutdownTimeoutMs, allowedHosts | unchanged | | secretApiKey, onlyEvaluateLocally, featureFlagsPollingInterval, waitForLocalDefinitions, client | no equivalent — see §4 |

Then:

  • Remove posthog-node from package.jsonunless you use it for your own analytics capture. Check with rg "posthog-node" first.
  • Drop projectApiKey/host from FireweaveRuntimeConfig if they were only there to satisfy the old adapter's validation. Keep host if you want the runtime-level allowlist check.
  • Update deployment config, secret stores, and CI: POSTHOG_HOSTFW_API_URL, POSTHOG_API_KEYFW_PROJECT_API_KEY. The new key is a Fireweave project key, not a re-labelled vendor key — it has to be issued from your Fireweave project.

2. What you do not have to change

| v2 | Status in 2.1 | | --- | --- | | client.flags.evaluate / getBooleanValue / … | works — the same object as client.controlPoints | | new InMemoryAdapter({ flags }) | unchanged | | Decision.flagKey, Exposure.flagKey, flagMetadata | unchanged | | FlagValueType, InMemoryFlagDefinition, ExpectedFlagType | unchanged | | capabilities.get().static.features.flags | still true (controlPoints: true added beside it) | | every other v2 export | unchanged |

client.flags === client.controlPoints — a getter returning the same instance, not a copy. It is marked @deprecated in JSDoc and is not scheduled for removal in the 2.x line; retiring it would need its own major and its own ADR. Renaming your call sites is cosmetic and can be deferred indefinitely.

The whole v2 surface is pinned by test/compat/v2-surface.compat.test.ts (runtime exports and behavior) and test/compat/v2-types.compat.ts (~40 type exports, checked by tsc --noEmit), so it cannot regress silently.

To find out whether you use the old name at all before touching anything, set FW_DEPRECATION_WARNINGS=1 in a non-production environment. It logs one notice per process; the SDK is silent otherwise, because a per-call warning at request volume is how deprecation notices get suppressed wholesale and then ignored.

3. Two type-level narrowings

'posthog' is no longer a member of BackendAdapter['name'] or Capabilities['runtime']['backend'].

  • A custom adapter declaring name: 'posthog' → use 'other'.
  • An exhaustive switch on backend with a case 'posthog' → that arm is unreachable; remove it.

Both are rare, and tsc points straight at them.

4. Local evaluation is gone

v2's vendor adapter could evaluate in-process from polled definitions with a secret key. 2.1 has no equivalent: caching is fw-server's concern, and both shipped adapters report localEvaluation: false.

If in-process evaluation is load-bearing for you — an air-gapped service, or a latency floor below one network hop — stay on v2 for now and tell us. The interface seam (AdapterRuntimeFeatures.localEvaluation / localOnly, AdapterResolution.fromCache, the STALE reason) is deliberately preserved for a future Fireweave-native cache (ADR-0006).

5. Worth re-checking

  1. DEFAULT_ALLOWED_HOSTS changed contents while keeping its name. It now lists Fireweave hosts, not vendor hosts. Code doing allowedHosts: [...DEFAULT_ALLOWED_HOSTS, 'mine.example'] keeps compiling and silently stops permitting the old endpoints. That is intended — verify it matches your deployment.
  2. Move durable attributes to registerTarget. Attributes you resend on every evaluation can be registered once per login. Per-request attributes still override stored properties, so the two compose — this is an optimization, not a cutover. Note that registerTarget returns { ok } rather than throwing (it sits in sign-in paths); log ok: false, because a silently unregistered target is exactly how targeting rules end up matching nobody.
  3. sdkVersion is now accurate. capabilities.get().static.sdkVersion returned 0.1.0 in v2 regardless of the package version; it now tracks package.json and is pinned by a test.

6. Verify

npm install @fireweaveai/sdk@^3
npx tsc --noEmit                                  # catches §3
<your test command>
rg -n "@fireweaveai/sdk/posthog|PostHogAdapter"   # expect no hits

At runtime:

const caps = client.capabilities.get();
// backend:                'fireweave'   (was 'posthog')
// localEvaluation:        false
// features.flags:         true          ← must still be true
// features.controlPoints: true

If backend is still 'inmemory' somewhere you expected to be live, the remote adapter was never wired in — check which adapter the runtime was constructed with.

Rollback

npm install @fireweaveai/sdk@2   # re-add posthog-node if you removed it

Revert the adapter swap and the env vars. No data migration is involved, so rollback is code and config only.


Renaming flagscontrolPoints safely

If you do decide to adopt the new name, scope the edit. flags is an ordinary word: your repo very likely contains feature-flag code, config keys, DB columns, and flags variables that have nothing to do with this SDK.

Rename only .flags accesses whose receiver is provably a FireweaveClient — traceable to a new FireweaveClient(...), an imported binding assigned from one, or a parameter annotated FireweaveClient.

Never rename:

| Looks similar | Why it stays | | --- | --- | | new InMemoryAdapter({ flags: … }) | SDK option key, unchanged | | flagKey, flagMetadata, FlagValueType, InMemoryFlagDefinition | SDK API, unchanged | | ofClient.getBooleanValue(...) | the OpenFeature client, not the Fireweave client | | features.flags in the capability matrix | still true; removing it fails conformance | | your own flags variables, featureFlags, CLI --flags, flags columns | not this SDK | | another vendor's SDK (ldClient.variation, flagd, Unleash) | not this SDK |

Do not run a repo-wide flagscontrolPoints replacement — not with sed, not with editor replace-all. Go call site by call site, and when a receiver is ambiguous, leave it. A missed cosmetic rename costs nothing; a wrong one breaks unrelated code.

Development

npm install          # from sdks/node
npm run build        # emit dist/ (package exports resolve to it)
npm run verify       # typecheck + unit + integration + compat + conformance + smoke
npm run smoke        # cross-runtime smoke (Node leg)

bun test packages/sdk/test/unit packages/sdk/test/integration packages/sdk/test/compat
bun  scripts/smoke-runtimes.mjs
deno run --allow-read scripts/smoke-runtimes.mjs

Documentation

Full docs live in docs/: quickstart · remote adapter · extensions · OpenFeature · runtimes · testing · migration · troubleshooting · ADRs.

License

MIT.