# Node.js

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

```bash
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.

```ts
// 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.

```ts
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](/docs/sdk/failures).

## 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](/docs/sdk/browser) as `bootstrap`. See [evaluateAll and bootstrap](/docs/sdk/evaluate-all).

## 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.

Source: https://splitch.dev/docs/sdk/node