Basestack Docs
Frontend

Open Feature Web SDK

The Basestack Open Feature Web SDK provider allows you to use Basestack Feature Flags with the Open Feature standard, providing a vendor-neutral, portable feature flag solution for web applications. This provider bridges Basestack's feature flag infrastructure with Open Feature's standardized API, giving you the flexibility to switch providers without changing your code.

Open Feature is an open standard for feature flag management that provides a consistent API across different providers. With this provider, you can leverage Open Feature's excellent developer experience including type safety, context-aware evaluation, and a standardized API while using Basestack as your feature flag backend.

Preview Status: This provider is currently in preview and still under active development. Basic feature flag functionality is supported, but advanced features like evaluation context and user identity targeting are still in the works. We recommend using this provider if you only need basic feature flag functionality.

Getting started

Install

Install the Open Feature Web SDK, core package, and the Basestack provider. The @openfeature/web-sdk provides the core Open Feature functionality for browsers, while @basestack/openfeature-provider connects it to Basestack's API.

Install the SDK
npm install @openfeature/web-sdk @openfeature/core @basestack/openfeature-provider
pnpm install @openfeature/web-sdk @openfeature/core @basestack/openfeature-provider
yarn add @openfeature/web-sdk @openfeature/core @basestack/openfeature-provider
bun add @openfeature/web-sdk @openfeature/core @basestack/openfeature-provider

Environment Variables

Configure your environment variables to connect to your Basestack Feature Flags project. The variable names depend on your build tool (Vite uses VITE_, Next.js uses NEXT_PUBLIC_, etc.).

When it comes to environment variables, pay attention to the framework you're using. For example, NEXT_PUBLIC_ is specific to Next.js, while in Vite.js, it would be VITE_. Example VITE_FEATURE_FLAGS_PROJECT_KEY= or FEATURE_FLAGS_PROJECT_KEY=

.env
# BASESTACK FEATURE FLAGS
FEATURE_FLAGS_PROJECT_KEY=""
FEATURE_FLAGS_ENVIRONMENT_KEY=""

You can find your project and environment keys in your Basestack Feature Flags Dashboard.

Make sure to add your .env file to .gitignore to keep your keys secure. Never commit sensitive credentials to version control.

Initialize the Provider

Create and configure the Basestack provider, then set it as the default provider for Open Feature. The provider handles API communication, caching, and automatic flag refreshing.

src/main.ts
import { OpenFeature } from '@openfeature/web-sdk';
import { createBasestackWebProvider } from "@basestack/openfeature-provider/web";

const provider = createBasestackWebProvider({
  apiUrl: "https://flags-api.basestack.co/v1",
  projectKey: import.meta.env.FEATURE_FLAGS_PROJECT_KEY, // or process.env for Node-based tools
  environmentKey: import.meta.env.FEATURE_FLAGS_ENVIRONMENT_KEY,
  prefetch: true, // Prefetch all flags on initialization
  refreshIntervalMs: 30_000, // Refresh flags every 30 seconds
});

try {
  await OpenFeature.setProviderAndWait(provider);
  console.log('OpenFeature provider initialized successfully');
} catch (error) {
  console.error('Failed to initialize provider:', error);
}

The provider configuration includes:

  • apiUrl: Your Basestack API endpoint
  • projectKey & environmentKey: Your Basestack credentials
  • prefetch: Whether to fetch all flags on initialization
  • refreshIntervalMs: How often to refresh flags automatically (in milliseconds)

Use Flags in Your Application

Once initialized, get a client instance and use it to evaluate flags throughout your application. The client provides type-safe methods for different flag value types.

src/main.ts
import { OpenFeature } from '@openfeature/web-sdk';
import { createBasestackWebProvider } from "@basestack/openfeature-provider/web";

// ... provider initialization ...

const client = OpenFeature.getClient();

// Get boolean flag value
const isHeaderEnabled = client.getBooleanValue('header', false);

if (isHeaderEnabled) {
  console.log("Header is enabled");
  // Show new header
} else {
  // Show default header
}


// Get object flag value
const config = client.getObjectValue('checkout-config', {});

The client provides methods for different value types:

  • getBooleanValue(key, defaultValue): Get a boolean flag
  • getObjectValue(key, defaultValue): Get an object/JSON flag

Advanced Usage

Flag Details

Get detailed information about flag evaluations, including metadata and reasons:

src/main.ts
const client = OpenFeature.getClient();

// Get boolean flag details
const details = client.getBooleanDetails('header', false);

console.log(details.value); // The flag value
console.log(details.variant); // The variant name
console.log(details.reason); // Why this value was returned
console.log(details.flagMetadata); // Additional metadata

// Similar methods exist for other types
const objectDetails = client.getObjectDetails('config', {});

Framework Integration

Vanilla JavaScript / TypeScript

For vanilla JavaScript applications, initialize the provider in your entry point:

src/main.ts
import { OpenFeature } from '@openfeature/web-sdk';
import { createBasestackWebProvider } from "@basestack/openfeature-provider/web";

async function initApp() {
  const provider = createBasestackWebProvider({
    apiUrl: "https://flags-api.basestack.co/v1",
    projectKey: import.meta.env.FEATURE_FLAGS_PROJECT_KEY,
    environmentKey: import.meta.env.FEATURE_FLAGS_ENVIRONMENT_KEY,
    prefetch: true,
    refreshIntervalMs: 30_000,
  });

  await OpenFeature.setProviderAndWait(provider);
  
  const client = OpenFeature.getClient();
  
  // Use flags throughout your app
  const showNewFeature = client.getBooleanValue('new-feature', false);
  
  if (showNewFeature) {
    // Initialize new feature
  }
}

initApp();

Configuration Options

The createBasestackWebProvider function accepts the following configuration:

OptionTypeRequiredDefaultDescription
apiUrlstringYes-Basestack API endpoint URL
projectKeystringYes-Your Basestack project key
environmentKeystringYes-Your Basestack environment key
prefetchbooleanNofalseWhether to fetch all flags on initialization
refreshIntervalMsnumberNo30000How often to refresh flags automatically (milliseconds)

Best Practices

1. Initialize Provider Early

Initialize the provider as early as possible in your application lifecycle to ensure flags are available when needed:

// Initialize before rendering
await OpenFeature.setProviderAndWait(provider);
// Then render your app

2. Use Appropriate Default Values

Always provide sensible default values that represent the "off" or "safe" state:

// Good: Safe default
const isEnabled = client.getBooleanValue('risky-feature', false);

// Avoid: Unsafe default
const isEnabled = client.getBooleanValue('risky-feature', true);

3. Set Evaluation Context

Provide user context for targeted flag evaluation:

const context = {
  targetingKey: userId,
  email: userEmail,
  plan: userPlan,
};

client.setContext(context);

4. Handle Provider Errors

Always handle provider initialization errors gracefully:

try {
  await OpenFeature.setProviderAndWait(provider);
} catch (error) {
  console.error('Failed to initialize provider:', error);
  // Fallback to default behavior or show error message
}

5. Use Flag Details for Debugging

Use getDetails methods when you need to understand why a flag returned a specific value:

const details = client.getBooleanDetails('feature', false);
console.log('Flag reason:', details.reason);
console.log('Flag metadata:', details.flagMetadata);

6. Optimize Refresh Intervals

Balance freshness with performance by setting appropriate refresh intervals:

// Frequent updates for critical flags
refreshIntervalMs: 10_000, // 10 seconds

// Less frequent for stable flags
refreshIntervalMs: 60_000, // 1 minute

Troubleshooting

Provider Not Initializing

If the provider fails to initialize:

  1. Check Environment Variables: Ensure your project and environment keys are set correctly
  2. Verify API URL: Confirm the apiUrl is correct and accessible
  3. Check Network: Verify your application can reach the Basestack API endpoint
  4. Review Console: Check browser console for detailed error messages

Flags Always Returning Default Values

If flags always return default values:

  1. Check Flag Keys: Verify the flag key matches what's configured in Basestack
  2. Verify Credentials: Ensure project and environment keys are correct
  3. Check Provider Status: Ensure the provider initialized successfully
  4. Inspect Network: Check browser network tab to see if API calls are being made

Flags Not Updating

If flags aren't updating:

  1. Check Refresh Interval: Flags refresh based on refreshIntervalMs. Wait for the interval or reduce it
  2. Verify Prefetch: If prefetch is enabled, flags are fetched on initialization
  3. Check Provider Events: Listen to ConfigurationChanged events to detect updates
  4. Manual Refresh: Consider implementing manual refresh if needed

Type Errors

If you're getting TypeScript errors:

  1. Install Types: Ensure @openfeature/core types are installed
  2. Check Imports: Verify you're importing from the correct packages
  3. Type Assertions: Use type assertions for object values when needed

Performance Issues

If you're experiencing performance problems:

  1. Increase Refresh Interval: Reduce API calls by increasing refreshIntervalMs
  2. Disable Prefetch: If you don't need all flags, set prefetch: false
  3. Use Caching: The provider includes built-in caching, but you can optimize further
  4. Lazy Load: Consider lazy loading flags that aren't needed immediately