Quickstart
Use Gates through OpenFeature — the CNCF-standard feature-flag API. Register the Lucerna provider once, then every read goes through the vendor-neutral @openfeature/server-sdk, so your application code never imports a Lucerna SDK directly.
Every evaluation is one round trip to the Gates server-side engine: no background poller, no exposure queue, nothing to close. That makes the provider a natural fit for serverless and edge handlers.
1. Get your server key
In the dashboard, open Settings → API keys and copy the server key (ck_srv_…). It carries the gates:evaluate grant the provider needs, and it picks the environment: production key, production rules. The publishable ck_client_… key is refused at startup.
2. Install
pnpm add @lucerna-dev/gates-openfeature @lucerna-dev/gates-node @openfeature/server-sdknpm install @lucerna-dev/gates-openfeature @lucerna-dev/gates-node @openfeature/server-sdkbun add @lucerna-dev/gates-openfeature @lucerna-dev/gates-node @openfeature/server-sdk@lucerna-dev/gates-node and @openfeature/server-sdk are peer dependencies of the provider.
3. Register the provider
Once, at startup:
import { OpenFeature } from "@openfeature/server-sdk";
import { LucernaProvider } from "@lucerna-dev/gates-openfeature";
await OpenFeature.setProviderAndWait(
new LucernaProvider({
serverKey: process.env.LUCERNA_SERVER_KEY!,
onError: (error) => console.error("[gates]", error.message),
}),
);Wire onError: reads never throw, so without it a misconfigured key serves safe defaults ("everything off") silently.
4. Read flags and experiments
const client = OpenFeature.getClient();
// targetingKey becomes the Gates userId; other attributes become traits.
const context = { targetingKey: user.id, plan: user.plan };
// Feature flag → true / false
if (await client.getBooleanValue("new_billing", false, context)) {
// show the new billing page
}
// Experiment → variant name, or your default when the user isn't in it
const variant = await client.getStringValue("checkout_test", "control", context);Boolean reads answer flags (kill switches folded in — a thrown switch reads false). String reads answer experiment variants, and the exposure is recorded server-side on the same request. Gates has no number or object flags, so those reads answer your default with TYPE_MISMATCH.
That's it. Next: the reference, using the provider in NestJS, or Vercel's Flags SDK.