splitchAlpha

DocsSDKnode.md

Node.js.

Evaluate on the request path from a Node server, with one client for the process.

npm install @splitch/sdk

Node 24 or newer. The package is ESM only, so a CommonJS project reaches it through await import("@splitch/sdk"). Construction performs no I/O, so build the client once at module scope and share it for the life of the process: a client per request throws away the local Exposure-dedup cache and re-counts subjects that a shared client would have collapsed.

// splitch.ts
import { createSplitchClient } from "@splitch/sdk";

const clientKey = process.env.SPLITCH_CLIENT_KEY;
if (!clientKey) throw new Error("SPLITCH_CLIENT_KEY is required");

export const splitch = createSplitchClient({ clientKey });

Throwing on a missing credential is deliberate. A client constructed without one throws SDK_CREDENTIAL_CONFIGURATION_INVALID anyway, and failing at import time puts the error in the boot log rather than in the first user's request.

On the request path

A Client Key is what a server uses to evaluate. It is public by design and safe on a server; the secret API Key cannot call evaluate at all. The SDK generates an idempotency key for each call. Supply a stable key when your application may retry an uncertain request.

import express from "express";
import { splitch } from "./splitch";

const app = express();

app.get("/checkout", async (req, res) => {
  const enabled = await splitch.evaluate("new-checkout", {
    targetingKey: req.user.id,
    defaultValue: false,
  });

  res.send(enabled ? renderNewCheckout() : renderCurrentCheckout());
});

This call never throws on a platform failure and never retries. On any such failure it returns your defaultValue, logs through logger.error, and reports reason: "ERROR" in evaluateDetails. Your handler keeps serving; the loud log is what stops that from becoming a silent outage. Local key failures still throw: SDK_CONTEXT_INVALID for an invalid explicit key, or SDK_IDEMPOTENCY_KEY_UNAVAILABLE when an omitted key cannot be generated. See Failure behavior.

Rendering a page in one round trip

A server-rendered page that reads many Flags should not make one request per Flag. evaluateAll resolves every Flag in the credential's App and Environment at once and fires no Exposure; each fresh assignment carries an Exposure Ticket the browser redeems on first read. Serialize the result into the page and hand it to the browser client as bootstrap. See evaluateAll and bootstrap.

Keep it off the user path

Admin screens, support tooling, and debugging read a Flag with peekVariant, which fires no Exposure and needs an API Key. Recording an Exposure outside the real user path inflates the experiment's denominator and biases the result, so the two calls are deliberately separate methods on separate credentials.

CI and deploy checks use verify: the same shape as evaluateDetails, no Exposure, safe to run repeatedly on either credential.