Offline & snapshots
Build a fully offline client from a captured snapshot — real evaluation, zero network. For CI, tests, and air-gapped runtimes.
Sometimes you want real flag evaluation with no network at all — a CI job, a deterministic test, an air-gapped runtime. A snapshot is just the two SDK wire bodies captured to disk; the client evaluates the real rules against it.
The snapshot shape
A snapshot is the bodies of GET /sdk/flags and GET /sdk/experiments:
// snapshot.json
{
"flags": /* body of GET /sdk/flags */,
"experiments": /* body of GET /sdk/experiments */
}Load it
fromFile / fromSnapshot build an Engine — the heavyweight client — from the captured blob. (Everyday flag reads use configure + new Client(user); here you build an isolated, offline Engine.)
import { Engine } from "@shipeasy/sdk/server";
// from a file (Node only — reads with node:fs)
const engine = Engine.fromFile("./snapshot.json");
// or from a parsed object you already hold (works anywhere)
const engine = Engine.fromSnapshot({ flags, experiments });
engine.getFlag("new_checkout", { user_id: "u1" });Evaluations run the real eval against the snapshot. init() / initOnce() / track() are no-ops, and override* setters still apply on top — handy for forcing a specific case in a test.
fromFile reads the file with node:fs. In a browser, an edge runtime, or
anywhere without a filesystem, fetch or import the JSON yourself and pass it to
fromSnapshot.
When to use it
- CI / tests — deterministic evaluation with no live dependency.
- Air-gapped or offline runtimes — ship a snapshot alongside the build.
- Reproducing a bug — capture production rules once and replay them locally.
For seeding individual values without a snapshot, use forTesting() + overrides instead.