@flagz-io/node
v0.1.0
Published
Official Node.js SDK for Flagz — runtime control for modern systems.
Maintainers
Readme
@flagz-io/node
Official Node.js SDK for Flagz — the runtime-control platform powering progressive delivery and safe feature rollouts.
Wraps the Flagz evaluation API (POST /v1/evaluate, POST /v1/evaluate/bulk) with:
- In-process TTL cache per
(flag, user). - Bulk evaluation that warms the cache for a user's entire env in one call.
- Typed accessors (
bool/string/int/json) with safe fallbacks. - Configurable timeout, retries with exponential backoff + jitter.
- Optional background polling to reduce staleness without SSE.
onEvaluationhook for telemetry / analytics.
Install
npm install @flagz-io/nodeRequires Node.js >= 20 (uses native fetch and AbortController).
Quick start
import { FlagzClient } from "@flagz-io/node";
const flagz = new FlagzClient({
baseURL: "https://flagz.example.com",
apiKey: process.env.FLAGZ_API_KEY!, // ff_...
cacheTTLMs: 5_000,
pollIntervalMs: 30_000,
onEvaluation: (e) => metrics.increment("flagz.eval", { reason: e.reason }),
});
const [showNewCheckout] = await flagz.bool("new-checkout", userId, false);
if (showNewCheckout) {
// ...
}API
new FlagzClient(options)
| Option | Default | Description |
| ----------------- | ------- | ---------------------------------------------------------- |
| baseURL | — | Flagz API base URL. |
| apiKey | — | Project API key (ff_...). |
| cacheTTLMs | 5000 | Per-entry cache TTL. 0 disables the cache. |
| timeoutMs | 3000 | Per-request timeout. |
| maxRetries | 2 | Retries for 5xx / 408 / 429 / network errors. |
| retryBackoffMs | 100 | Base backoff; doubles each attempt with jitter. |
| pollIntervalMs | 0 | If > 0, refreshes bulk snapshots for warm users on a tick. |
| onEvaluation | — | Callback fired for every evaluation, including cache hits. |
| fetch | global | Override fetch (useful in tests). |
Methods
flagz.evaluate(flag, user, fallback); // -> { key, value, reason }
flagz.evaluateBulk(user); // -> { flags: [...] }
flagz.bool(flag, user, fallback); // -> [boolean, reason]
flagz.string(flag, user, fallback); // -> [string, reason]
flagz.int(flag, user, fallback); // -> [number, reason]
flagz.json(flag, user, fallback); // -> [object, reason]
flagz.clearCache();
flagz.close(); // stops pollingreason is one of flag_not_found | disabled | user_override | rollout | error | cache.
Behavior notes
- Stickiness. The server hashes
flag_key:user_id(FNV-32a) into a 0–99 bucket, so a user stays in the same bucket per flag. - Cache freshness. TTL is local to the process. With multiple instances, expect each replica to converge within
cacheTTLMsof an admin change (the server itself invalidates internal snapshots via Redis pub/sub). - Polling.
pollIntervalMsonly refreshes users that have already been seen byevaluateBulk. Single-flag evaluations are not auto-refreshed; rely on TTL. - Failure mode. Every typed accessor returns the supplied fallback if the API is unreachable or returns the wrong type, with
reason: "error".
Development
npm install
npm run build # tsup → dist/{index.js,index.cjs,index.d.ts}
npm test # vitest
npm run typecheck
npm run lintReleasing
See PUBLISHING.md for the full end-to-end flow: scope setup, auth, version bumping, npm provenance via GitHub Actions, and recovery from a bad release.
