Skip to main content
Official React SDK for Westyx Nexus - configuration and feature flags, delivered to the browser and kept current.

Latest release

v0.16.0

What’s new in v0.16.0

  • Breaking: getSecret() removed, along with NexusPublicKeyError and NexusSecretNotFoundError. This SDK only ever holds a public key, and the backend never sends a secret to one, so the method could only ever throw. No change needed unless your code called it.

What’s new in v0.15.0

  • A live stream that never connects is reported. When the client gives up before its first successful connection it says so once - through the logger you configured, or on console.warn if you configured none. Reads keep succeeding on the TTL in that state, so without this a component looks healthy and its values simply stop changing. A connection lost after connecting is reported by useNexusStreamStatus() instead. See SSE live updates.
  • The stream request carries only the API key and Accept. Both are all the server needs, which is one fewer name a deployment’s CORS configuration has to allow.

What’s new in v0.14.0

  • The package type-checks on React 18 as well as 19. Both majors the peer range admits are compiled and tested in CI, in every leg.
  • An unchanged object-valued config does not re-render. A composite value’s identity is held across a sync that changed nothing.
  • The API key stays out of component state. The provider’s internal configuration signature carries a digest of the key rather than the key itself.
  • This package is client-only, and the documentation now says so: a server render produces loadingFallback.

What’s new in v0.13.0

  • A composite (object or array) resolution in the OpenFeature bridge carries an integer beyond Number.MAX_SAFE_INTEGER as its exact decimal string - at any depth, in objects and arrays alike, so the resolved value survives JSON.stringify. Ordinary numbers are untouched, and the scalar number resolution still answers TYPE_MISMATCH for the same value.

What’s new in v0.12.1

  • The OpenFeature provider re-fetches targeted values only when the configuration actually changed. The client reports every observable change, a stream state transition included; the provider tells the two apart through NexusClient.snapshotRevision, so a reconnect or a fall-back-to-polling costs no request and triggers no re-render.
  • NexusClient.snapshotRevision - how many times the snapshot’s contents have been replaced. subscribe also fires for connection state and for the billing and quarantine flags, and this is what distinguishes a configuration change from those.
  • Closing the provider releases the identity it was holding, including from a refresh that had been requested but not yet sent.
  • The bridge exports NexusProviderOptions, so a caller can name the type of the options object it passes.
  • The bridge requires this SDK at >=0.12.1, and its published type entry points resolve correctly from both ESM and CommonJS consumers.

What’s new in v0.12.0

  • The OpenFeature provider resolves per user. An evaluation context carrying a targetingKey selects a per-user boolean evaluation through the Nexus AB Testing add-on, so rollout percentages and cohort rules apply. The request happens on setContext, not on evaluation, so reading a flag stays synchronous; one round trip covers every flag in the snapshot. See OpenFeature.
  • The provider takes options: logger and addonSuppressionMs, validated at construction.
  • The provider’s resolutions were corrected: an error resolution reports DEFAULT or ERROR rather than STATIC beside the error code, an unknown flag reports FLAG_NOT_FOUND, every scalar resolution carries a variant, a number resolution no longer converts a boolean or a string into a number, and a JSON null is reported as a missing value rather than as 0.
  • hasFlag(key) and getFlagKeys() on the client - whether the service defines a flag at all, and every flag key in the snapshot.

Breaking changes

  • evaluateAB() and useEvaluateAB() take string attribute values (Record<string, string>). The endpoint’s request type is string-to-string and answers anything else with a 400, so a call passing a number or a boolean was already failing; it is a compile error now.

What’s new in v0.11.0

This release rebuilds the client on a core shared with the Angular and Vue SDKs, so the three behave identically.
  • Every request has a deadline. A connection a middlebox stops answering can no longer stop background refresh for the life of the page.
  • A refresh is coalesced. An event burst, a TTL expiry and a manual sync arriving together produce one request, and a slow response can never be applied over a newer one.
  • Unmounting releases everything - the live stream, every timer, every listener.
  • Large integers survive the decode. An integer above 2^53 arrives as a bigint rather than rounded; every value a double holds exactly stays a number.
  • Configuration is validated at construction, naming the option, the reason and the value.
  • Status hooks track their own state. useNexusStreamStatus() and useNexusBillingOverdue() re-render when the stream or the billing state changes, not only when a sync replaces the cache.
  • Built on useSyncExternalStore, so a concurrent render cannot show one flag’s old value beside another’s new one.
  • Correct package resolution - import resolves ESM, require resolves CommonJS, each with matching types.
  • Tested on React 18 and 19.

Breaking changes

  • A public key (wxp_) is now required; any other key is rejected at construction.
  • useSecret() has been removed - a browser client holds a public key, so it could only ever return undefined.
  • useNexusSyncedAt() returns epoch milliseconds rather than a Date.
  • NexusLogger takes structured fields: (message, fields?), with a warn level added.
  • ttlMs: 0 and an empty sseReconnectCooldown array are rejected rather than coerced into a zero delay.

Where to start

How it works

One bulk GET /v1/sync fills an in-memory snapshot. A live event stream pushes changes as they happen; when it is unavailable the TTL drives polling instead, and reads keep being served from the last snapshot throughout. A read never blocks.

Public keys only

A browser SDK ships inside a bundle any visitor can read, so it accepts only a public key (wxp_). Public keys cannot read secrets, and the backend’s Double-Gate check ties them to one service host. Secrets belong in a backend SDK.