@release-anchor/js
v1.1.3
Published
ReleaseAnchor JavaScript SDK for feature flag evaluation
Downloads
328
Maintainers
Readme
JavaScript / Node.js SDK for ReleaseAnchor feature flags. Works in Node.js and browser environments. Zero dependencies.
Documentation · npm · releaseanchor.com
Installation
npm install @release-anchor/js
# or
pnpm add @release-anchor/js
# or
yarn add @release-anchor/jsQuick start
import { ReleaseAnchor } from "@release-anchor/js";
const client = new ReleaseAnchor({
apiKey: process.env.RELEASE_ANCHOR_KEY,
});
const result = await client.evaluate("dark-mode", "user-123");
if (result.value) {
// feature is on for this user
}
// result: { value: boolean, matchedRuleType: string | null, error: object | null }evaluate() returns an EvaluateResponse object with:
value— the boolean resultmatchedRuleType—"STATIC" | "SEGMENT" | "PERCENTAGE" | nullerror— populated on technical failures (network, timeout, etc.),nullon success
Configuration
const client = new ReleaseAnchor({
apiKey: "ra_xxx", // Required — get from the API Keys page
apiVersion: "v1", // "v1" | "v2". Default: "v1"
baseUrl: "https://...", // Override API base URL. Default: https://api.releaseanchor.com
timeout: 5000, // Request timeout in ms. Default: 5000
cacheTtlMs: 30_000, // In-memory cache TTL in ms. Set to 0 to disable. Default: 30000
defaultValue: false, // Fallback value on technical errors. Default: false
strict4xx: false, // Throw StrictHttpError on unexpected 4xx. Default: false
logger: console.warn, // Called on technical errors. Default: console.warn
});evaluate(flagKey, userIdentifier, defaultValue?)
Evaluates a single flag for a user. Results are cached per flagKey + userIdentifier for cacheTtlMs milliseconds. Concurrent calls for the same key are deduplicated — only one HTTP request is made.
const result = await client.evaluate("dark-mode", "user-123");
// Per-call defaultValue overrides the instance-level default
const result = await client.evaluate("dark-mode", "user-123", true);evaluateBulk(flagKey, userIdentifiers[], defaultValue?)
Evaluates a single flag for multiple users in one request.
const results = await client.evaluateBulk("dark-mode", ["user-1", "user-2"]);
// results: Record<string, EvaluateResponse>
for (const [userId, result] of Object.entries(results)) {
if (result.value) console.log(`${userId}: feature on`);
}Missing keys in the server response are filled with a fallback entry. Extra keys are ignored.
Cache management
client.clearCache(); // Clear entire cache
client.clearCache("dark-mode"); // Clear all entries for a flag
client.clearCache("dark-mode", "user-123"); // Clear a specific entryCleanup
Call destroy() during app shutdown or test teardown to stop the background cache cleanup timer:
client.destroy();
// afterAll(() => client.destroy()); // in test suitesError handling
Technical errors (network, timeout, 401, 429, 5xx, parse failure) are caught internally, logged via logger, and returned as a fallback response — the SDK never throws by default.
const result = await client.evaluate("dark-mode", "user-123");
if (result.error) {
// result.error.type: "NETWORK_ERROR" | "TIMEOUT" | "UNAUTHORIZED" |
// "RATE_LIMITED" | "HTTP_ERROR" | "PARSE_ERROR"
// result.error.message: string
}
// result.value is always safe to use — it will be defaultValue on errorstrict4xx (development helper)
Set strict4xx: true to throw StrictHttpError on unexpected 4xx responses instead of silently falling back. Useful for catching misconfiguration early:
import { ReleaseAnchor, StrictHttpError } from "@release-anchor/js";
const client = new ReleaseAnchor({ apiKey: "...", strict4xx: true });
try {
const result = await client.evaluate("dark-mode", "user-123");
} catch (err) {
if (err instanceof StrictHttpError) {
console.error("Unexpected HTTP error:", err.status);
}
}Timeouts are never thrown — detect them via
result.error.type === "TIMEOUT".
TypeScript
The SDK ships with full TypeScript types — no @types package needed.
import { ReleaseAnchor, type EvaluateResponse, StrictHttpError } from "@release-anchor/js";
const client = new ReleaseAnchor({ apiKey: process.env.RELEASE_ANCHOR_KEY! });
const result: EvaluateResponse = await client.evaluate("my-flag", userId);License
MIT — see LICENSE
