Skip to content

React SDK

FlagPulse has an official React SDK published to npm: flagpulse-react.

View source code on: GitHub.

Install

bash
npm install flagpulse-react

Requires react >= 18 as a peer dependency.

What it does

  • Fetches flags from your self-hosted FlagPulse backend (GET /api/v1/flags, x-sdk-key header — see Quickstart)
  • Caches the flag list in localStorage so repeat loads don't wait on a network call
  • Connects to server updates and refreshes state automatically (see Realtime Updates)
  • Exposes a FlagPulseProvider + useFlag hook, and a lower-level FlagPulseClient if you don't want React context

Setup

Wrap your app with FlagPulseProvider, passing the base URL of your FlagPulse deployment and the environment's SDK key.

tsx
import { FlagPulseProvider, useFlag } from "flagpulse-react";

function App() {
  return (
    <FlagPulseProvider
      baseUrl="https://flags.example.com"
      sdkKey="YOUR_SDK_KEY"
    >
      <FeatureFlagsDemo />
    </FlagPulseProvider>
  );
}

Provider props

PropRequiredDefaultDescription
baseUrlYesPublic URL of your FlagPulse deployment
sdkKeyYesThe environment's SDK key from the dashboard
ttlNo300000 (5 min)Cache TTL in milliseconds
childrenYesYour app

Reading flags: useFlag

tsx
function FeatureFlagsDemo() {
  const newCheckout = useFlag("new_checkout", false);
  const themeColor = useFlag("theme_color", "blue");
  const maxItems = useFlag("max_items", 10);

  return (
    <div>
      {newCheckout ? <CheckoutV2 /> : <CheckoutV1 />}
      <p>Theme: {themeColor}</p>
    </div>
  );
}

useFlag(key, fallback) returns the flag's value if it exists and is enabled, otherwise the fallback you pass — so the fallback also doubles as your type hint (boolean, string, or number flags all work the same way).

Direct client usage (no React context)

If you don't want a provider — e.g. using flags outside components, in a state store, or in a non-React part of your app — use FlagPulseClient directly:

tsx
import { FlagPulseClient } from "flagpulse-react";

const client = new FlagPulseClient({
  sdkKey: "YOUR_SDK_KEY",
  baseUrl: "https://flags.example.com",
  ttl: 300000,
});

await client.init();

const isEnabled = client.get("new_checkout", false);

Client methods

MethodDescription
init()Fetches flags and connects the live-update listener
get(key, fallback)Returns a flag's value, or fallback if missing/disabled
identify(context)Stores contextual data (e.g. user attributes) for later use
onUpdate(callback)Subscribes to flag update events
reset()Clears cached state
destroy()Disconnects the live-update listener

FlagPulseProvider is a thin wrapper around this client — using one or the other is a matter of whether you want React context or manual control.

Full example

tsx
import { FlagPulseProvider, useFlag } from "flagpulse-react";

function App() {
  return (
    <FlagPulseProvider baseUrl="https://flags.example.com" sdkKey="YOUR_SDK_KEY">
      <Dashboard />
    </FlagPulseProvider>
  );
}

function Dashboard() {
  const enableReports = useFlag("enable_reports", false);
  return <main>{enableReports ? <ReportsPage /> : <OverviewPage />}</main>;
}

A note on SDK keys in the browser

Since this runs client-side, the SDK key is visible in the browser's network tab. That's expected for FlagPulse's intended use (rollout toggles, UI variants) — the key only scopes which environment's flags are returned, not who can see the response. Don't put anything sensitive behind a flag value if your deployment needs stricter access control.