Feature FlagsSDKsJavaScript & NodeJS

JavaScript & Node SDK Reference (v1.0.3)

Seamless integration with JavaScript/NodeJS streamlines the testing and development of features across production and various environments. This SDK effortlessly integrates into any JavaScript-based environment, allowing you to leverage this capability in projects like Vue, Svelte, or other JavaScript frameworks.

Getting started

ℹ️

We only support ESM (ECMAScript Modules) in the browser or server environment. If you are using CommonJS, you will need to use a bundler like Webpack or Rollup to bundle your code.

Examples

Install

First, let’s install some packages!

npm install @basestack/flags-js

or with Script Tag

<script type="module" src="https://unpkg.com/@basestack/flags-js"></script>

Environment Variables

Here are the example environment variables needed for this guide. Feel free to rename them according to your project’s requirements:

ℹ️

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_BASE_URL= or Node.js FEATURE_FLAGS_BASE_URL=

.env
# BASESTACK FEATURE FLAGS
FEATURE_FLAGS_BASE_URL="https://flags.basestack.co//api/v1" # or your own URL
FEATURE_FLAGS_PROJECT_KEY=""
FEATURE_FLAGS_ENVIRONMENT_KEY=""

Create a new instance

You can find these parameter values in your project’s settings

main.js
import { FlagsSDK } from "@basestack/flags-js";
 
// Basic Initialization
const client = new FlagsSDK({
  projectKey: "your-project-key",
  environmentKey: "your-environment-key",
});
 
// Custom Configuration Example
const advancedClient = new FlagsSDK({
  baseURL: "https://your-basestack-hosted-app-domain.com/api/v1",
  projectKey: "your-project-key",
  environmentKey: "your-environment-key",
  preloadFlags: ["header", "footer"],
  cache: {
    enabled: true,
    ttl: 10 * 60 * 1000, // 10-minute cache
    maxSize: 50, // Limit cache to 50 entries
  },
});

That’s it! Your app is now fully equipped to leverage feature flags and other powerful functionalities. To make the most of Basestack’s capabilities, simply follow the instructions provided in the supported methods documentation.

Usage

main.js
import { FlagsSDK } from "@basestack/flags-js";
 
const client = new FlagsSDK({
  projectKey: "your-project-key",
  environmentKey: "your-environment-key",
});
 
// Preload flags on initialization (optional)
// This will fetch the flags and cache them for future use
// But you can still fetch flags on-demand using getFlag()
await client.init();
 
// Fetching a Single Flag
async function checkFeatureFlag() {
  try {
    const headerFlag = await client.getFlag("header");
 
    if (headerFlag.enabled) {
      console.log("Header feature is enabled");
      console.log("Payload:", headerFlag.payload);
      // Additional flag properties
    } else {
      console.log("Header feature is disabled");
    }
  } catch (error) {
    console.error("Failed to fetch flag:", error);
  }
}
 
// Fetching All Flags
async function listAllFlags() {
  try {
    const { flags } = await client.getAllFlags();
 
    flags.forEach((flag) => {
      console.log(`Flag: ${flag.slug}`);
      console.log(`Enabled: ${flag.enabled}`);
      console.log(`Description: ${flag.description}`);
      // Additional flag properties
    });
  } catch (error) {
    console.error("Failed to fetch flags:", error);
  }
}
 
// Cache Management
function manageCaching() {
  // Clear entire cache
  client.clearCache();
 
  // Clear cache for a specific flag
  client.clearFlagCache("header");
}
 
// Practical Example
 
async function renderFeature() {
  try {
    const headerFlag = await client.getFlag("new-header-design");
 
    if (headerFlag.enabled) {
      // Render new header design
      renderNewHeader(headerFlag.payload);
    } else {
      // Render default header
      renderDefaultHeader();
    }
  } catch (error) {
    // Fallback to default implementation
    renderDefaultHeader();
  }
}

Server Implementation

In a server environment like Node or Serverless, you can use the SDK as usual because it uses the Fetch API, which is supported in Node.js.

⚠️

The Fetch API is available in Node.js starting from version 18.0.0.

If your project uses a Node version earlier than 18, you will need to modify the Fetch API implementation, which is supported by our SDK.

Here is an example using cross-fetch as the Fetch API implementation:

main.js
import fetch from "cross-fetch";
import { FlagsSDK } from "@basestack/flags-js";
 
// Initialize FlagsSDK with cross-fetch as fetch implementation
const client = new FlagsSDK({
  projectKey: "your-project-key",
  environmentKey: "your-environment-key",
  fetchImpl: fetch,
});

Here is an example using Axios as the Fetch API implementation:

main.js
import axios from 'axios';
import { FlagsSDK } from '@basestack/flags-js';
 
// Axios wrapper to match fetch API signature
const axiosFetch: typeof fetch = async (input, init) => {
  const { method, headers, body } = init || {};
  const response = await axios({
    url: input.toString(),
    method,
    headers,
    data: body,
  });
 
  return new Response(JSON.stringify(response.data), {
    status: response.status,
    statusText: response.statusText,
    headers: response.headers,
  });
};
 
// Initialize FlagsSDK with axios as fetch implementation
const client = new FlagsSDK({
  projectKey: 'your-project-key',
  environmentKey: 'your-environment-key',
  fetchImpl: axiosFetch,
});

TypeScript Support

The SDK is built with TypeScript. Therefore, when used in a TypeScript project, it comes with basic type inference out of the box.

main.ts
/** Configuration for caching mechanism */
export interface CacheConfig {
  /** Enable or disable caching (default: true) */
  enabled?: boolean;
  /** Time-to-Live for cache entries in milliseconds (default: 5 minutes) */
  ttl?: number;
  /** Maximum number of cache entries (default: 100) */
  maxSize?: number;
}
 
/** SDK Configuration Options */
export interface SDKConfig {
  /** Base URL for the feature flag service (optional) */
  baseURL?: string;
  /** Project identification key (required) */
  projectKey: string;
  /** Environment identification key (required) */
  environmentKey: string;
  /** Caching configuration options */
  cache?: CacheConfig;
  /** Custom fetch implementation (optional) */
  fetchImpl?: typeof fetch;
  /** Flags to preload during initialization */
  preloadFlags?: string[];
}
 
/** Feature flag data structure */
export interface Flag {
  slug: string;
  enabled: boolean;
  payload?: unknown;
  expiredAt?: Date | null;
  createdAt: Date;
  updatedAt: Date;
  description: string;
  error?: boolean;
}

SDK Reference

Initialisation options

PropertyTypeDescriptionRequiredDefault Value
baseURLstringSpecifies the target URL to point to.falsehttps://flags.basestack.co/api/v1
projectKeystringSpecifies the project to retrieve data from.truenull
envKeystringSpecifies the project environment from which to retrieve flags.truenull
preloadFlagsstring[]List of flags to preload during initialization.false[]
cache -> enabledbooleanEnables or disables caching of flags.falsetrue
cache -> ttlnumberTime-to-live for cached flags in milliseconds.false5 * 60 * 1000
cache -> maxSizenumberMaximum number of flags to store in the cache.false100

Available Methods

PropertyDescriptionEnvironment
init() => Promise<void>Initiates the flags request, enabling caching capabilities.Browser & Node & Serverless
clearCache(): voidClears all cached flags.Browser & Node & Serverless
clearFlagCache(slug: string): voidClears the cache for a specific flag identified by the slug.Browser & Node & Serverless
getFlag(slug: string): Promise<Flag>Retrieves a specific flag by its slug.Browser & Node & Serverless
getAllFlags(): Promise<{ flags: Flag[] }>Retrieves all flags.Browser & Node & Serverless