Skip to main content

Overview

In this guide you add shipdit to a Node.js service: one client per process, a ready() call at startup, and per-request evaluation context. Flag checks run in memory against the environment’s snapshot, so they add no network call to a request. This page uses new-checkout and search-variant from Define flags in code, plus the max-retries number flag and checkout-payload JSON flag from Create number and JSON flags. Add all four to shipd.config.ts and run shipd push so the generated FlagDefinitions includes them.

Install

shipdit requires Node.js 20 or later.

Create a server SDK key

  1. In the dashboard, open your project and select the environment.
  2. Go to SDK keys and click Create SDK key.
  3. Enter a name, set Key type to server, and create it.
  4. Copy the key (shipd_sdk_server_…). It is shown once.
.env
Each SDK key belongs to one environment. See Keys for all credential types.

Create the client module

Create the client once and import it everywhere. Pass a default for every flag. Defaults are served until the first snapshot arrives and whenever the edge can’t be reached.
src/lib/shipd.ts
stream: true enables realtime updates over WebSocket. Without it, the client polls every 30 seconds.
The SDK uses globalThis.WebSocket, which exists in Node.js 22 and later. On Node.js 20, pass a constructor from the ws package, or omit stream to poll only.
createClient throws if sdkKey is empty. The client connects to https://edge.useshipd.com, and stream: true adds the https://ws.useshipd.com gateway. See createClient for every option.

Wait for ready at startup

Call ready() once before you accept traffic. It resolves when the first snapshot loads, or after readyTimeoutMs (5 seconds by default). It never rejects for network errors.
src/server.ts

Evaluate per request

A server client handles many users at once, so pass the evaluation context on each call. On a server client, identify() only records the user’s traits for audience insights. It never changes the context that later evaluations use.
src/app.ts
The same code works in Express:
src/routes/checkout.ts
Without a userId, percentage rollouts can’t assign a bucket. The server SDK doesn’t infer location, so pass country or other traits yourself. See Target users.

Shut down cleanly

close() stops polling, closes the WebSocket, and flushes pending events. Await its promise before exiting; it resolves after delivery finishes, fails, or reaches the timeout (5 seconds by default).
src/server.ts

What happens on failure

Evaluation methods never throw. Pass onError to log background failures. For the full model, see Local evaluation. For error messages, see Errors.

Next