OpenFeature providers that talk to the BaseStack flags API from Node.js services and browser applications. The package exposes two purpose-built providers and a thin shared core so you can adopt BaseStack-managed flags everywhere while staying compliant with the OpenFeature specification.
- ✅ Works with the official
@openfeature/server-sdkand@openfeature/web-sdk - ⚡️ Built with Bun + tsdown for a small, ESM-only artifact
- 🧪 Comes with Vitest and Biome configs so the package is ready for CI
bun add @basestack/openfeature-provider
# or npm, yarn etcThe package is ESM-only and targets runtimes that provide fetch (Node.js 18+, Bun, modern browsers). Supply a custom fetch implementation if you run on older environments.
import { OpenFeature } from "@openfeature/server-sdk";
import { createBasestackServerProvider } from "@basestack/openfeature-provider/server";
OpenFeature.setProvider(
createBasestackServerProvider({
projectKey: process.env.BASESTACK_PROJECT_KEY!,
environmentKey: process.env.BASESTACK_ENVIRONMENT_KEY!,
// apiUrl: "https://flags-api.basestack.co/v1", // override for self-hosted gateways
cacheTtlMs: 30_000,
refreshIntervalMs: 15_000,
}),
);
const client = OpenFeature.getClient("flags");
const enabled = await client.getBooleanValue("beta-dashboard", false);import { OpenFeature } from "@openfeature/web-sdk";
import { createBasestackWebProvider } from "@basestack/openfeature-provider/web";
await OpenFeature.setProviderAndWait(
createBasestackWebProvider({
projectKey: window.BASESTACK_PROJECT_KEY,
environmentKey: window.BASESTACK_ENVIRONMENT_KEY,
refreshIntervalMs: 60_000, // keep the in-memory snapshot in sync
}),
);
const client = OpenFeature.getClient("web-flags");
const currentTheme = client.getStringValue("theme", "light");| Option | Type | Default | Description |
|---|---|---|---|
projectKey |
string |
required | Project identifier used to authorize requests. |
environmentKey |
string |
required | Environment identifier used to scope flags. |
apiUrl |
string |
https://flags-api.basestack.co/v1 |
Override when self-hosting the BaseStack API. |
cacheTtlMs |
number |
30_000 (server) / Infinity (web) |
How long a cached flag stays fresh. Set to 0 to disable caching. |
refreshIntervalMs |
number |
0 (server) / 30_000 (web) |
Background refresh cadence. |
prefetch |
boolean |
false (server) / true (web) |
Fetch the full flag snapshot during initialize. |
requestTimeoutMs |
number |
5_000 |
Client-side timeout for each HTTP request. |
headers |
Record<string, string> |
{} |
Additional headers merged into every request. |
fetch |
(input, init) => Promise<Response> |
global fetch |
Supply your own fetch implementation when needed. |
Both providers cache the GET /flags snapshot in memory, respect the TTL you configure, and fall back to the caller-provided default value if your BaseStack API is unreachable.
bun install # download dependencies
bun test # run Vitest
bun run lint # Biome lint
bun run format # Biome format
bun run build # tsdown build → dist/The build script bundles every entry point (index, server, and web) into the dist/ directory alongside type declarations so this package can be published to npm under the MIT license.