@splitlab/node
v0.8.2
Published
Node.js server SDK for SplitLab A/B testing and feature flags
Readme
@splitlab/node
Node.js server SDK for SplitLab A/B testing and feature flags. Per-request evaluation, event batching, and HTTP request context enrichment.
Installation
npm install @splitlab/nodeQuick Start
import { SplitLabServer } from '@splitlab/node';
const splitlab = new SplitLabServer({
apiKey: 'ot_live_abc123',
baseUrl: 'https://splitlab.cc',
});
await splitlab.initialize();
// Per-request evaluation (< 1ms, no network)
const variant = splitlab.getVariant('checkout-btn', 'user-42');
const enabled = splitlab.isFeatureEnabled('dark-mode', 'user-42', { plan: 'pro' });
// Event tracking (batched and flushed automatically)
splitlab.track('user-42', 'purchase', { value: 49.99, currency: 'USD' });
// Clean shutdown
await splitlab.destroy();Request Context
For full-stack apps, withContext() parses the HTTP request and enriches events with server-side properties (UA, URL, cookies, UTM params, device/session IDs):
import express from 'express';
const app = express();
app.get('/checkout', (req, res) => {
const ctx = splitlab.withContext(req);
// Evaluate with device ID from cookie (stable across anonymous → logged-in)
const variant = ctx.getVariant('checkout-btn');
// Track enriched with browser, OS, pathname, UTM, etc.
ctx.track('page_view');
// Set device/session cookies on response
for (const cookie of ctx.getResponseCookies()) {
res.setHeader('Set-Cookie', cookie);
}
res.render('checkout', { variant });
});Server-Side Bootstrap (SSR)
Generate bootstrap data on the server to hydrate the browser SDK with zero flicker:
app.get('/app', (req, res) => {
const ctx = splitlab.withContext(req);
const bootstrap = ctx.getBootstrapData(req.user?.id);
// Pass to client — the browser SDK hydrates instantly, no config fetch needed
res.render('app', { bootstrap: JSON.stringify(bootstrap) });
});On the client:
import { SplitLabClient } from '@splitlab/js-client';
const client = new SplitLabClient({
apiKey: 'ot_live_abc123',
baseUrl: 'https://splitlab.cc',
bootstrap: JSON.parse(window.__BOOTSTRAP__),
});
// Hydration is synchronous — getVariant() works immediatelyConfiguration
const splitlab = new SplitLabServer({
apiKey: string; // Your org API key
baseUrl: string; // API server URL
ingestUrl?: string; // Ingest server URL (defaults to baseUrl)
configRefreshInterval?: number; // Config polling interval in ms (default: 30000)
flushInterval?: number; // Event flush interval in ms (default: 10000)
flushSize?: number; // Max buffered events before auto-flush (default: 100)
onConfigUpdate?: () => void; // Callback when config changes
environment?: string; // Environment key (default: 'production')
});API
splitlab.initialize(): Promise<void>
Fetches config, starts polling and flush timers.
splitlab.getVariant(experimentKey, distinctId, attributes?): string | null
Returns the assigned variant, or null if excluded.
splitlab.isFeatureEnabled(flagKey, distinctId, attributes?): boolean
Returns whether the flag is enabled for this user.
splitlab.evaluateAll(distinctId, attributes?): EvalResult
Evaluates all experiments and flags at once.
splitlab.track(distinctId, eventName, properties?): void
Queues an event. Auto-flushes when buffer reaches flushSize.
splitlab.flush(): Promise<void>
Sends all buffered events to the ingest service.
splitlab.withContext(req): RequestContext
Creates a request-scoped context with enriched properties from HTTP headers/cookies.
splitlab.destroy(): Promise<void>
Flushes remaining events and stops all timers.
ctx.getVariant(experimentKey, distinctId?): string | null
Evaluate with optional distinct ID override (defaults to device ID from cookie).
ctx.track(eventName, properties?, distinctId?): void
Track an event enriched with request context (UA, URL, referrer, UTM, device/session IDs).
ctx.getResponseCookies(): string[]
Returns Set-Cookie headers for device ID (2yr) and session ID (30min sliding).
ctx.getBootstrapData(distinctId?, attributes?): BootstrapData
Generates bootstrap data for client-side SDK hydration.
Building
npm run build # ESM + CJS + types → dist/
npm run dev # Watch mode