Skip to content

Quickstart

Show your first flag in the browser in under a minute.

1. Get your client key

In the dashboard, open Settings → API keys and copy the client key:

ck_client_prod_8d5afc124938bed869d2

It's public — safe to ship in frontend code. The browser only ever receives decisions, never your targeting rules. The key also picks the environment — and the SDK refuses secret keys (ck_srv_…, ck_key_…) at startup, so one can't slip into your bundle.

2. Install

bash
pnpm add @lucerna-dev/gates-browser @lucerna-dev/identity
bash
npm install @lucerna-dev/gates-browser @lucerna-dev/identity
bash
bun add @lucerna-dev/gates-browser @lucerna-dev/identity

3. Use it

Create one identity and one client for the whole app:

ts
import { createGates } from "@lucerna-dev/gates-browser";
import { createIdentity } from "@lucerna-dev/identity";

export const identity = createIdentity({ apiKey: "ck_client_prod_…" });

export const gates = createGates({
  clientKey: "ck_client_prod_…",
  identity,
});

When the user logs in, tell the identity — decisions refetch automatically:

ts
identity.identify({ userId: user.id });
identity.trait("plan", user.plan);

Then check gates anywhere:

ts
if (gates.flag("new_billing")) {
  // show the new billing page
}

const variant = gates.experiment("checkout_test"); // name or null

if (!gates.switch("payments")) {
  // payments are paused
}

Checks are instant and never throw. Before decisions load they answer safe defaults — flags false, experiments null.

4. React

tsx
import { Feature, GatesProvider, useFlag } from "@lucerna-dev/gates-browser/react";

<GatesProvider client={gates}>
  <App />
</GatesProvider>;

function Billing() {
  const newBilling = useFlag("new_billing"); // re-renders on change

  return (
    <Feature name="checkout_v2" fallback={<OldCheckout />}>
      <NewCheckout />
    </Feature>
  );
}

There's more — <KillSwitch>, <Experiment>/<Variant> and the rest of the hooks live in the React guide. Shipping Astro or Preact? Those have their own guides too.

UX only

Browser decisions show and hide UI. Always re-check permissions on your backend — anything in the browser can be tampered with.

That's it. Next: the Browser SDK reference.

Lucerna Developer Docs