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 🙏

© 2024 – Pkg Stats / Ryan Hefner

feature-with-flags

v1.0.0

Published

A feature flag library for Javascript applications

Downloads

2

Readme

feature-with-flags

feature-with-flags is a typescript library to implement feature flags for javascript applications. Name inspired from Sheldon Coopers fun with flags program.

What are feature flags?

Feature flags (also commonly known as feature toggles) are a software engineering technique that turns select functionality on and off during runtime, without deploying new code.

Installation

Install the package using npm or yarn by


npm install --save feature-with-flags

or

yarn add feature-with-flags

Usage


# ES6

import FeatureFlag from "feature-with-flags";

# CommonJs

const FeatureFlag = require('feature-with-flags');

Initialise FeatureFlag and pass feature flag configuration to it


const featureFlags = new FeatureFlag(FEATURE_FLAGS_CONFIGURATION);

const { isActive } = featureFlags();

You can get the status of a feature flag by passing some of its details to the isActive method


const { status, message } = isActive(FEATURE_FLAG_DETAILS);

status is a boolean which tells if a feature flag is enabled or not

message is a null | string, a message if there's wrong with the passed in feature flag details

# enable a feature by

// If status is true, apply the new logic if not use the same existing logic

if(status) {
  useNewLogic();
} else {
  useExistingLogic();
}

Internals

In this section, we will discuss the internals of feature-with-flags library.

Feature Flag Configurations Object

feature-with-flags expects feature flag configurations object in the below shape

  • Sample configuration
  
 const featureFlagConfigurations = {
  featureFlag1: {
   enable: true
  },
  featureFlag2: {
   enable: false
  }
 }
  • Complex configuration
  
 const featureFlagConfigurations = {
  featureFlag1: {
   enable: true,
   activationStrategies: ['UserRoleActivationStrategy', 'ReleaseDateActivationStrategy'],
   roles: ['ROLE_1', 'ROLE_2']
  },
  featureFlag2: {
    enable: false,
    activationStrategies: "UserWithIDActivationStrategy",
    userIDs: ['USER_ID_1', 'abc', 'xyz'],
  },
   .... other feature flags
 }

Examples of feature flags which are very granual

  • Show the feature only for users who has ADMIN role
  • Enable the feature for just US region
  • This feature will be shown only at specific date
  • and many more.....

You see the list goes on.

Activation Stratigies

UserRoleActivationStrategy

ActivationStrategy implementation based on roles of the current user. As far as the user has at least one of configured roles then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["UserRoleActivationStrategy"],

    userRoles:["admin", "phoenix"], //This key is must a provided for as UserRoleActivationStrategy looks for userRoles in the config,
    .... other configurations
  },
}
   
Context:

When the featureFlag contains UserRoleActivationStrategy then the end user needs to pass the key userRole while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");
 
 const { isActive } = featureFlagConfig;
 
 const featureFlagContext = {
 
  // This is a must provided key
  userRole: 'LOGGED_IN_USER_ROLE' //feature-with-flags will take this key and lookover the userRoles provided in the configuration.
  
 }
 const { status, message } = isActive("alpha", featureFlagContext);
 

UserWithIDActivationStrategy

ActivationStrategy implementation based on the ID of the current user. As far as the user has at least one of configured IDs then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["UserWithIDActivationStrategy"],

    userIDs:["ID1", "ID2"], //This key is must a provided for as UserWithIDActivationStrategy looks for userIDs in the config,

    .... other configurations
  },
}
   
Context:

When the featureFlag contains UserWithIDActivationStrategy then the end user needs to pass the key userID while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {

    // This is a must provided key
   // feature-with-flags will take this key and lookover the userIDs provided in the configuration.

    userID: 'LOGGED_IN_USER_ID' 

 }
 const { status, message } = isActive("alpha", featureFlagContext);

RegionActivationStrategy

ActivationStrategy implementation based on the region of the current user. As far as the user has at least one of configured regions then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["RegionActivationStrategy"],

    regions:["region1", "region2"], //This key is must a provided for as RegionActivationStrategy looks for regions in the config,

    .... other configurations
  },
}
   
Context:

When the featureFlag contains RegionActivationStrategy then the end user needs to pass the key region while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {
     // This is a must provided key
    //feature-with-flags will take this key and lookover the regions provided in the configuration.

    region: 'USER_REGION'
 };

 const { status, message } = isActive("alpha", featureFlagContext);

DeviceTypeActivationStrategy

ActivationStrategy implementation based on the device type of the current user. As far as the user has at least one of configured device types then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["DeviceTypeActivationStrategy"],

   // This key is must a provided for as DeviceTypeActivationStrategy looks for deviceTypes in the config,
    deviceTypes:["desktop", "mobile"], 

    .... other configurations
  },
}
   
Context:

When the featureFlag contains DeviceTypeActivationStrategy then the end user needs to pass the key deviceType while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {

  // This is a must provided key
  deviceType: navigator.userAgent //feature-with-flags will take this key and lookover the deviceTypes provided in the configuration.
 };

 const { status, message } = isActive("alpha", featureFlagContext);

TenantActivationStrategy

ActivationStrategy implementation based on the tenant id of the current user. As far as the user has at least one of configured tenant ids then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["TenantActivationStrategy"],

    // This key is must a provided for as TenantActivationStrategy looks for tenantIDs in the config,
    tenantIDs:["tenant1", "tenant2"],

    .... other configurations
  },
}
   
Context:

When the featureFlag contains TenantActivationStrategy then the end user needs to pass the key tenantID while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {

    // This is a must provided key
   //feature-with-flags will take this key and lookover the tenantIDs provided in the configuration.
  tenantID: "TENANT_ID"
 };

 const { status, message } = isActive("alpha", featureFlagContext);

ClientIdActivationStrategy

ActivationStrategy implementation based on the client id of the current user. As far as the user has at least one of configured client ids then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["ClientIdActivationStrategy"],

    // This key is must a provided for as ClientIdActivationStrategy looks for clientIDs in the config,
    clientIDs:["client1", "client2"],

    .... other configurations
  },
}
   
Context:

When the featureFlag contains ClientIdActivationStrategy then the end user needs to pass the key clientID while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {

   // This is a must provided key
  //feature-with-flags will take this key and lookover the clientIDs provided in the configuration.
  clientID: "CLIENT_ID"

 };

 const { status, message } = isActive("alpha", featureFlagContext);

ReleaseDateActivationStrategy

ActivationStrategy implementation based on the release date. When the current date is beyond or equal to the user provided release date then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {

  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["ReleaseDateActivationStrategy"],

    // releaseDate should be in "November 21, 2021" or "12/26/2021" // MM/DD/YYYY format. 
    releaseDate: "November 21, 2021", //This key is must a provided for as ReleaseDateActivationStrategy looks for releaseDate in the config,

    .... other configurations
  },
}
   
Context:

 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const { status, message } = isActive("alpha");

DateTimeActivationStrategy

ActivationStrategy implementation based on the release date with time. When the current date is beyond or equal to the user provided release date then the feature will be active.

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["DateTimeActivationStrategy"],

    // Format: DD/MM/YYY/HOURS:MINUTES:SECONDS
    releaseDateWithTime: "11/11/2021/16:50:10,
   // Note: releaseDateWithTime should be in this format. This key is must a provided for as DateTimeActivationStrategy looks for releaseDateWithTime in the config,

    .... other configurations
  },
}
   
Context:

 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const { status, message } = isActive("alpha");

FlexibleRolloutActivationStrategy

ActivationStrategy implementation based on the unique id of the current user. As far as the user threshold value is within the range of user provided rolloutPercentage then the feature will be active.

How does this strategy work?

If you want to enable a feature for a fixed percentage of users randomly, you need to pass the percentage range (0 -100) and a unique identifier for each logged in user typically userID. Internally feature-with-flags calculates user threshold value (a unique number that is always the same based on feature flag name & unique user id) check with rolloutPercentage, if the user threshold value is less than rolloutPercentage then the feature will be active

Usage

Configuration:
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true,
    activationStrategies: ["FlexibleRolloutActivationStrategy"],

    rolloutPercentage: 40, // This key is must a provided for as FlexibleRolloutActivationStrategy looks for rolloutPercentage in the config,

    .... other configurations
  },
}
   
Context:

When the featureFlag contains FlexibleRolloutActivationStrategy then the end user needs to pass a unique identifier userID while checking the status.


 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const featureFlagContext = {

  // This is a must provided key
  userID: "ANY_UNIQUE_IDENTIFIER_ACROSS_USERS"

 }

 const { status, message } = isActive("alpha", featureFlagContext);

default

If the user didn't pass any activation strategy, feature-with-flags consider it as default activation strategy, the status of this feature flag will be depend on the enabled key.

- If using normal configuration
# sample example

featureFlagConfigurations: {
  alpha: { // Name of the feature flag
    enable: true
  },
}
   
Context:

 const featureFlagConfig = new FeatureFlag("YOUR_FEATURE_FLAG_CONFIGURATION");

 const { isActive } = featureFlagConfig;

 const { status, message } = isActive("alpha");

Generic error messages

In this section, you will find all the types of messages feature-with-flags will send to the user when there is an error. This will help the developer to debug why the feature flag is not working as expected.


## When the user passes a feature flag name that is not part of his/her feature flag configuration

message: feature flag name: FEATURE_FLAG_NAME is not found, please check your configuration.

## In the above Activation Strategies section you will find the required key in config & context for each strategy

// Case 1: If the user didn't pass or misspells the required CONFIG key for the activation strategy

Message: `Activation strategy: ${YOUR_STRATEGY_NAME} missing lookup ${REQUIRED_STRATEGY_CONFIG_KEY} in the config for feature flag: ${YOUR_FEATURE_FLAG_NAME}`

// Case 2: If the user didn't pass or misspells the required CONTEXT key for the activation strategy

Message: `Activation strategy: ${YOUR_STRATEGY_NAME} missing lookup ${REQUIRED_STRATEGY_CONTEXT_KEY} in the context for feature flag: ${YOUR_FEATURE_FLAG_NAME}`

// Case 3: If the user didn't pass or misspells the required CONFIG & CONTEXT key for the activation strategy

Message: `Activation strategy: ${YOUR_STRATEGY_NAME} requires ${REQUIRED_STRATEGY_CONFIG_KEY} in the config object and ${REQUIRED_STRATEGY_CONTEXT_KEY} in the context object as lookup for feature flag: ${YOUR_FEATURE_FLAG_NAME}`

// Case 4: When the user passes a feature flag name that is not present in the configuration

Message: `feature flag name: ${YOUR_FEATURE_FLAG_NAME} is not found, please check the configuration`

// Case 5: When the user passed context key value not matched with the value of configuration for an activation strategy

Message: `${CONTEXT_VALUE} is not found in ${CONFIG_KEYS}` 

Ex: userId: 123 is not found in userID's configuration

Contact

Contact @Manoj Kumar Gangavarapu ([email protected]) in case of any queries.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT