Skip to content

Browser quickstart

@flagwire/sdk-js is the framework-independent browser SDK. It sends an evaluation context to the FlagWire edge and keeps rules out of the client bundle.

Terminal window
pnpm add @flagwire/sdk-js

Create the client in browser-only code and keep it for the application lifecycle.

import { createClient } from "@flagwire/sdk-js";
const flags = createClient({
clientKey: import.meta.env.VITE_FLAGWIRE_CLIENT_KEY,
context: {
key: "user-123",
attributes: { region: "ap-south", appVersion: "2.4.1" },
},
});
await flags.ready();

Client keys begin with pk_live_. They are intended for browser use and authorize remote evaluation only. Never expose a server key beginning with sk_live_ in frontend source, public environment variables, HTML, logs, or a client bundle.

Every read requires a safe application default.

const redesigned = flags.get("checkout-redesign", false);

Use detail() when you need the selected variant, evaluation reason, or flag version.

const detail = flags.detail("checkout-redesign");

If initialization or refresh fails, FlagWire uses a validated bootstrap or warm cache when one is available. Otherwise, get() returns the default supplied by your code.

const unsubscribe = flags.on("update", (changedKeys) => {
if (changedKeys.includes("checkout-redesign")) {
renderCheckout(flags.get("checkout-redesign", false));
}
});

Interval polling is disabled by default. Visible activation and focus refreshes check the environment version first; an evaluation occurs only when configuration changed. Set stream: true when you want version notifications to trigger a prompt refresh.

const flags = createClient({
clientKey: import.meta.env.VITE_FLAGWIRE_CLIENT_KEY,
context: { key: "user-123" },
stream: true,
});
await flags.setContext({
key: "user-456",
attributes: { plan: "starter" },
});

Context attributes can be strings, finite numbers, booleans, or arrays of strings. Keep the context stable and include only attributes needed for targeting. Reordered attributes and string-array members are canonicalized and do not trigger a refresh.

Use manual activation when your application has a trusted engagement boundary:

const flags = createClient({
activation: "manual",
clientKey: import.meta.env.VITE_FLAGWIRE_CLIENT_KEY,
context: { key: "user-123" },
});
await flags.start();

refresh() performs a version check. refresh({ force: true }) deliberately performs a remote evaluation even when the version is unchanged.

unsubscribe();
await flags.flush();
flags.close();

For server-rendered frameworks, create the client after hydration or inside a client component. Do not create a browser client during server rendering.

Use a server key from a secure local environment to generate declarations. Provide it as FLAGWIRE_SERVER_KEY through your shell or CI secret environment so it does not appear in source, a package script, or shell history.

Terminal window
pnpm dlx flagwire-typegen --out src/flags.gen.ts

Import the generated file once:

import "./flags.gen";

get() will then infer known flag keys and their value types.

Option Required Default Purpose
clientKey Yes — Public key beginning with pk_live_
context Yes — Evaluation key and up to 64 bounded attributes
activation No "visible" Immediate, visible-only, or manual network activation
baseUrl No https://edge.flagwire.dev FlagWire edge endpoint
bootstrap No — Validated snapshot available immediately
pollIntervalMs No false Optional visible-only version polling; minimum 30 seconds
refreshOnFocus No true Check version after a stale client regains focus
staleAfterMs No 300000 Age before a focus version check; minimum 30 seconds
stream No false Opt in to version notifications
exposureTracking No "automatic" Deduplicate automatic exposures, or disable exposure delivery

Next: React quickstart or targeting reference.