Node.js
Read flags on a Node server, with streaming updates and start-up validation.
A server client that resolves flags and learns of a change in about a second.
- An API key from API Keys
Read flags on a Node server, and learn about a change in about a second.
npm install @varia-bly/node
One client per process
waitForInitialization() resolves once variA/Bly has answered, so your first request does not race
the first fetch.
import { createClient } from '@varia-bly/node';
const client = createClient(process.env.VARIABLY_API_KEY!, {
baseUri: process.env.VARIABLY_BASE_URL,
timeout: 30,
});
await client.waitForInitialization();
| Option | Default | What it does |
|---|---|---|
baseUri | — | Your API host. Required: there is no default, so evaluations cannot reach an unintended one. |
timeout | 10 | Seconds before a request gives up. |
stream | off | Hold a socket open for change events. See below. |
onChange | — | Called after new values are cached. |
cache | — | Snapshot TTL and revalidation. |
Reading flags
// Everything, for one context.
const snapshot = await client.allFlags({ key: user.id });
const flags = snapshot.values();
// One flag, typed.
const redesign = await client.boolVariation('checkoutRedesign', { key: user.id }, false);
const layout = await client.stringVariation('checkoutLayout', { key: user.id }, 'control');
The key in the context is the user identifier — not your API key, and not a gate key. Rules and
user overrides match on it, so pass something stable per user. { key: '' } is the anonymous case,
which is what a server-rendered page usually wants.
Catch missing flags at start-up
const missing = await client.validateFlags(['checkoutRedesign', 'newPricing']);
if (missing.length > 0) throw new Error(`Flags not defined in Variably: ${missing.join(', ')}`);
A flag the project does not define raises FlagNotFoundError rather than returning the default you
passed. That is deliberate: a typo or an unseeded environment would otherwise be indistinguishable
from a flag that is switched off, and the application would run on defaults looking healthy.
validateFlags surfaces all of them at once, before a request path reaches whichever is read first.
Streaming, and when to leave it off
stream is off unless you pass stream: true, and the client polls either way. Turning it on holds
a WebSocket open so the server sees a change in about a second rather than at the next poll.
Leave it off wherever the process is expected to exit. If your build generates pages, an open socket keeps the process alive and the build hangs after the pages are written:
const isBuild = process.env.CLOUD_BUILD === 'true';
const client = createClient(apiKey, { baseUri, stream: !isBuild, timeout: 30 });
A socket that cannot connect, or drops, costs only that latency — polling carries on regardless.
Feeding the browser
If you also render in a browser, resolve on the server and pass the set down, so the first paint is right. See React.
export async function getServerSideProps() {
const snapshot = await client.allFlags({ key: '' });
return { props: { bootstrappedFlags: snapshot.values() } };
}