npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@rudderstack/featureflag-sdk-node

v1.1.1

Published

A flexible and extensible feature flag SDK that supports multiple providers and caching.

Readme

Feature Flag SDK

A flexible and extensible feature flag SDK that supports multiple providers and caching.

Features

  • Support for multiple feature flag providers (Amplitude, Flagsmith)
  • In-memory caching with customizable TTL
  • TypeScript support
  • Easy to extend with new providers
  • Local evaluation support

Basic Usage

The SDK uses remote evaluation by default. Before using any feature flag functions, you must first initialize the SDK using initFeatureFlagClient. Once initialized, the SDK provides four main functions for interacting with feature flags:

  • isFeatureEnabled - Check if a feature is enabled (cached)
  • getFeatureValue - Get the value of a feature flag (cached)
  • isFeatureEnabledLatest - Check if a feature is enabled (real-time)
  • getFeatureValueLatest - Get the value of a feature flag (real-time)
import {
  isFeatureEnabled,
  getFeatureValue,
  isFeatureEnabledLatest,
  getFeatureValueLatest,
  updateEnvironment,
  initFeatureFlagClient,
  FeatureFlagSDKError,
} from '@rudderstack/featureflag-sdk-node';

// initialize feature flag client
initFeatureFlagClient({
  provider: {
    type: 'flagsmith',
    apiKey: 'test-api-key',
  },
});

// Using cached functions (recommended for most use cases)
async function processEvent(event) {
  try {
    const isEnabled = await isFeatureEnabled('workspaceId', 'myFeature');
    if (isEnabled) {
      // process event
    }
  } catch (error) {
    if (error instanceof FeatureFlagSDKError) {
      // handle feature flag error
      console.error(`Feature flag error: ${error.message}`);
    }
  }
}

// Using latest functions (for startup or critical real-time updates)
async function start() {
  try {
    // Get fresh values during startup
    const features = await Promise.all([
      getFeatureValueLatest('workspaceId', 'routing'),
      getFeatureValueLatest('workspaceId', 'theme'),
    ]);
    // Initialize app with latest values and start
  } catch (error) {
    if (error instanceof FeatureFlagSDKError) {
      // handle feature flag error
      console.error(`Feature flag error: ${error.message}`);
    }
  }
}

SDK Configuration

The SDK configuration follows the FeatureFlagClientConfig interface, which includes the following options:

Cache Configuration

| Configuration Option | Description | Default Value | | -------------------- | --------------------------------------------------------------------------------------------------- | ------------- | | cache.enabled | Enable/disable feature flag caching. Note: Cache must be disabled when local evaluation is enabled. | true | | cache.ttlInSeconds | Time-to-live in seconds for cached values | 60 |

Provider Configuration

| Configuration Option | Description | Default Value | | -------------------------------- | --------------------------------------------------------------------------------------- | ------------- | | provider.type | The feature flag provider to use (required) | - | | provider.apiKey | API key for the feature flag provider (required) | - | | provider.timeoutInSeconds | Timeout in seconds for provider API calls | 60 | | provider.retryAttempts | Number of retry attempts for failed API calls | 3 | | provider.enableLocalEvaluation | Enable/disable local evaluation of feature flags. When enabled, cache must be disabled. | false | | provider.enableAnalytics | Enable/disable analytics reporting to the provider | true |

Default Traits Configuration

| Configuration Option | Description | Default Value | | -------------------- | ------------------------------------------------- | ------------- | | defaultTraits | Default traits to use for feature flag evaluation | new Map() |

Local Evaluation

The SDK supports local evaluation of feature flags, which allows you to evaluate flags without making a network request to the feature flag provider every time. Only an initial download of the flag definitions and targeting rules is required. The SDK will keep refreshing the flag definitions and targeting rules from the provider periodically.

Note: When local evaluation is enabled, caching is disabled. We implemented caching in combination with remote evaluation to reduce the number of API calls made to the feature flag provider and to increase the performance of the SDK. However, with local evaluation, all flags are evaluated locally without making network requests to the feature flag provider. Therefore, it does not make sense to have both caching and local evaluation enabled. We internally disable caching when local evaluation is enabled. Since caching is disabled, the behavior of cached and latest functions will be the same.

Enabling Local Evaluation

To enable local evaluation, you need to set provider.enableLocalEvaluation to true while calling the init function.

Passing User Traits

When using local evaluation, you need to pass user traits when evaluating flags. These traits are used to determine the flag value based on targeting rules.

You can pass traits when evaluating feature flags by providing an optional third parameter along with the workspace ID and feature name.

const isEnabled = await isFeatureEnabled('test-workspace', 'test-feature', {
  [TRAIT_KEYS.ORGANIZATION_ID]: 'test-org-id',
});

Note: When local evaluation is enabled, passing user traits becomes necessary for proper flag evaluation, especially for flags that use targeting rules based on these traits.

Benefits of Local Evaluation

  • Reduced Latency: Evaluates flags without network requests
  • Offline Support: Can work without an internet connection
  • Improved Performance: Faster flag evaluations for high-volume applications
  • Reduced API Usage: Minimizes calls to the feature flag provider

Limitations

  • Requires initial download of flag definitions
  • May not have the most up-to-date flag configurations

Cached vs Latest Functions

Cached Functions (isFeatureEnabled, getFeatureValue)

Recommended for:

  • Regular feature checks during runtime
  • Feature checks while processing events
  • Frequent feature flag queries
  • Performance-critical operations

Benefits:

  • Faster response times
  • Lower latency
  • Reduced server load
  • Better user experience

Latest Functions (isFeatureEnabledLatest, getFeatureValueLatest)

Using latest functions only makes sense if the SDK is configured to use remote evaluation. See Local Evaluation for more details on how caching is disabled when local evaluation is enabled.

Best for:

  • Application startup configuration
  • Features that need guaranteed latest values
  • One-time initialization
  • Critical business logic requiring real-time values

Note: These functions make direct calls to the feature flag provider and may have higher latency. Use them sparingly and only when necessary.

When to Use Latest Functions

  1. Application Initialization

    async function startupConfig() {
      // Get fresh values during startup
      const features = await Promise.all([
        getFeatureValueLatest('workspaceId', 'routing'),
        getFeatureValueLatest('workspaceId', 'theme'),
      ]);
      // Initialize app with latest values
    }
  2. Critical Business Features

    async function processPayment() {
      // Check latest feature state for critical operations
      const paymentConfig = await getFeatureValueLatest('workspaceId', 'paymentProcessing');
      // Process payment using latest configuration
    }

Remember: While latest functions provide real-time values, they come with additional latency and server load. Use them judiciously and prefer cached functions for regular operations.

Refreshing Feature Flags

updateEnvironment() - Force Cache Refresh

The updateEnvironment() function forces an immediate refresh of the locally cached environment data from the feature flag provider. This is useful when you know that feature flags have been updated on the server and want to ensure your application has the latest configuration.

Important Notes:

  • Currently implemented for the Flagsmith provider with local evaluation enabled (other providers use a no-op implementation)
  • Only effective when enableLocalEvaluation: true - without local evaluation, there's no local environment cache to refresh
  • It's a global operation that affects all workspaces
  • The provider manages cache invalidation internally
  • Safe to call with any provider or configuration - will no-op when not applicable

When to use:

  1. External notification of flag changes

    // Webhook handler for flag updates
    app.post('/webhooks/flagsmith', async (req, res) => {
      // Flag was updated in Flagsmith
      await updateEnvironment();
      res.status(200).send('OK');
    });
  2. Scheduled cache refresh

    // Refresh flags every 5 minutes
    setInterval(async () => {
      try {
        await updateEnvironment();
      } catch (error) {
        console.error('Failed to update environment:', error);
      }
    }, 5 * 60 * 1000);
  3. Manual cache invalidation

    import { updateEnvironment } from '@rudderstack/featureflag-sdk-node';
    
    async function refreshFlags() {
      try {
        await updateEnvironment();
        console.log('Feature flags refreshed successfully');
      } catch (error) {
        console.error('Failed to refresh feature flags:', error);
      }
    }

Usage with Local Evaluation:

When using local evaluation mode (enableLocalEvaluation: true), updateEnvironment() is particularly useful because the SDK caches the environment document locally. Calling this function ensures your local cache is synchronized with the latest configuration from Flagsmith.

Testing Feature Flags

The SDK allows you to mock feature flags and test your application against different feature flag combinations using the provided testing utilities.To test your code with different feature flag settings, you can use the MockFeatureFlagClient to define a list of flags to test against and their combinations, and itTestAllFeatureCombinations to run your tests against all those combinations automatically.

MockFeatureFlagClient

This client allows you to configure a list of feature flags to test against, you can also specify predefined combinations of those feature flags. If no combinations are provided, it will test your code against all possible combinations of the given feature flags:

// Test all possible combinations
const mockClient = new MockFeatureFlagClient({
  flags: [{ name: 'feature1' }, { name: 'feature2' }],
});

// Test specific combinations
const mockClient = new MockFeatureFlagClient({
  flags: [{ name: 'feature1' }, { name: 'feature2' }],
  combinations: [
    [
      { name: 'feature1', enabled: true },
      { name: 'feature2', enabled: false },
    ],
    [
      { name: 'feature1', enabled: false },
      { name: 'feature2', enabled: true },
    ],
  ],
});

itTestAllFeatureCombinations

This is a utility function that will run your tests against all possible combinations of the feature flags you have configured in the MockFeatureFlagClient. It is a jest.It like utility function that takes a test case and runs it multiple times, once for each possible combination of feature flags.

The utility automatically:

  • Mocks the feature flag client
  • Cycles through all combinations
  • Resets state between test suites
describe('My Feature Tests', () => {
  const mockClient = new MockFeatureFlagClient({
    flags: [{ name: 'feature1' }, { name: 'feature2' }],
  });

  itTestAllFeatureCombinations(mockClient, 'should handle all combinations', async () => {
    // Your test code here
    // Will run once for each possible combination
  });
});

A sample test case can be found in the sampleApp.test.ts file.