React SDK
FlagPulse has an official React SDK published to npm: flagpulse-react.
View source code on: GitHub.
Install
npm install flagpulse-reactRequires react >= 18 as a peer dependency.
What it does
- Fetches flags from your self-hosted FlagPulse backend (
GET /api/v1/flags,x-sdk-keyheader — see Quickstart) - Caches the flag list in
localStorageso repeat loads don't wait on a network call - Connects to server updates and refreshes state automatically (see Realtime Updates)
- Exposes a
FlagPulseProvider+useFlaghook, and a lower-levelFlagPulseClientif 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.
import { FlagPulseProvider, useFlag } from "flagpulse-react";
function App() {
return (
<FlagPulseProvider
baseUrl="https://flags.example.com"
sdkKey="YOUR_SDK_KEY"
>
<FeatureFlagsDemo />
</FlagPulseProvider>
);
}Provider props
| Prop | Required | Default | Description |
|---|---|---|---|
baseUrl | Yes | — | Public URL of your FlagPulse deployment |
sdkKey | Yes | — | The environment's SDK key from the dashboard |
ttl | No | 300000 (5 min) | Cache TTL in milliseconds |
children | Yes | — | Your app |
Reading flags: useFlag
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:
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
| Method | Description |
|---|---|
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
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.