Skip to main content

Implementing a feature using ConfigCat and LaunchDarkly

· 12 min read
Emil Kovačević
Code hard, debug harder.

Feature flagging services have become a crucial part of software development. They simplify the release of new software features by removing the complexity of the feature flagging system and allowing developers to concentrate on their software. In this article, we'll examine the ways of adding a new feature to a React application and compare the use of feature flags by integrating two well-known feature flagging services, ConfigCat and LaunchDarkly, into the application.

feature flags with launch darkly and configcat cover photo

What are feature flags and feature flag services?

Feature flags (also known as feature toggles) are a way to dynamically enable or disable specific functionality in software without making changes to code.

Feature flag services are platforms that provide a centralized management of feature flags and associated metadata. These services allow development teams to easily manage and deploy feature flags, monitor their usage and impact, and collaborate on flag management across the entire organization.

Introducing the College Campus Management System

As a demo application, we will use a college campus management system that keeps a record of students. This system has the capability to manage the student records by adding, removing, searching, and editing student information.

To showcase the use of feature flags, I will introduce a counting feature. The flag will dynamically update the "Student Record" heading with the total number of students and the sum of enrollment statuses for active and inactive students. The use of feature flags will allow controlled testing in a production environment, minimizing the risk of potential problems with the code.

students app photo

In the following sections, I will walk you through the initial layout of the application and the process of implementing the feature flag services. To manage the release, I'll enable user targeting to limit the feature to email addresses containing the @it.campus.com domain. By the end of this article, you will have a better understanding of how feature flags can be used to manage and release new software features in a safe and controlled manner.

To simplify the process of the feature flag implementation, I will first integrate ConfigCat, then make modifications to implement LaunchDarkly.

Note:

  • I am using the global React Context to add interactivity to the Student Record table.
  • I implemented the browser's local storage in the application to keep the record of students instead of connecting to an online database.

To create the project, I am using the Vite build tool.

To follow along, you will need:

After creating a directory on your system and opening your coding environment, you can run the following commands in the terminal:

  • npm create vite@latest
  • npm install
  • npm run dev

or you can clone the completed project containing both implementations from here.

If you are building the application from scratch, here is a sample of the data stored in the local storage.

[{"id":1,"isActive":true,"name":"Natalie Martinez"},{"id":2,"isActive":false,"name":"James Wilson"},{"id":3,"isActive":true,"name":"Samantha Rodriguez"}]

Preparing the application for feature flags

From the initial boilerplate, the App component received the global context and new child components building up the table:

import { DataProvider } from "./context/DataContext";
import TableHead from "./components/TableHead";
import TableBody from "./components/TableBody";
import TableFooter from "./components/TableFooter";

const App = () => {
return (
<main>
<DataProvider>
<table>
<caption>Student List</caption>
<TableHead />
<TableBody />
<TableFooter />
</table>
</DataProvider>
</main>
);
};

export default App;

To implement the new feature, I will create a new React component named "TableCaption" that adds the featured application functionality. This component will be conditionally rendered based on the feature flag value.

Let's have a quick look at the new component.

The "TableCaption" component holds all the new code within itself to prevent any negative impact on the rest of the application. From the global context, the component only listens for changes in the students variable, which ultimately contains the student record. This triggers a re-render and the application performs new calculations.

import DataContext from "../context/DataContext";
import { useContext, useEffect, useState } from "react";

const TableCaption = () => {
const { students } = useContext(DataContext);
const [countOfStudents, setCountOfStudents] = useState(0);
const [countOfActiveStudents, setCountOfActiveStudents] = useState(0);
const [countOfInactiveStudents, setCountOfInactiveStudents] = useState(0);

useEffect(() => {
const studentCount = JSON.parse(localStorage.getItem("students"));
setCountOfStudents(studentCount.length);
let activeCount = 0;
let inactiveCount = 0;
studentCount.forEach((student) => {
if (student.isActive) {
activeCount++;
} else {
inactiveCount++;
}
});
setCountOfActiveStudents(activeCount);
setCountOfInactiveStudents(inactiveCount);
}, [students]);

return (
<>
<caption>
{countOfStudents
? `Number of students: ${countOfStudents}. Active students: ${countOfActiveStudents}. Inactive students: ${countOfInactiveStudents}`
: "No students"}
</caption>
</>
);
};

export default TableCaption;

To use this component in the application, I will introduce a new feature flag named "captionCounterFlag". With it, the "TableCaption" component is going to be conditionally used, and depended on the value of the feature flag.

Creating the feature flag with ConfigCat

  1. Sign in to the ConfigCat Dashboard to create a new feature flag.

  2. In the dashboard, you can add a feature flag by clicking the Add feature flag option.

  3. Create a feature flag with the following details:

  • Name: captionCounterFlag
  • Key: captioncounterflag
  1. Click the ADD FEATURE FLAG button to create and save the feature flag.

  2. Add a new targeting rule by setting:

    • the comparison attribute to Email
    • the comparator to Contains(cleartext)
    • save the segment

configcat targeting rules photo

  1. Make sure to turn on the feature flag in your environment.
  2. Click on the VIEW SDK KEY button on the top right to view the key.

configcat flag setup photo

Accessing the ConfigCat feature flag from the application

To install the ConfigCat SDK for React run the following command:

npm i configcat-react

Let's modify the "main.jsx" file to import the ConfigCat SDK:

import React from "react";
import { ConfigCatProvider } from "configcat-react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<ConfigCatProvider
sdkKey="YOUR-SDK-KEY"
>
<App />
</ConfigCatProvider>
</React.StrictMode>
);

The ConfigCatProvider component uses the "configcat-react" library. The provider is passed the SDK key for accessing the ConfigCat service, which wraps around the App component enabling feature management for the entire application.

Let's add the flag in the App component:

import { useFeatureFlag } from "configcat-react";
import { DataProvider } from "./context/DataContext";
import TableHead from "./components/TableHead";
import TableBody from "./components/TableBody";
import TableFooter from "./components/TableFooter";
import TableCaption from "./components/TableCaption";

const App = () => {
const { value: captioncounterflagValue } = useFeatureFlag(
"captioncounterflag",
false,
{ identifier: "USER-ID", email: "[email protected]" }
);

return (
<main>
<DataProvider>
<table>
{captioncounterflagValue ? (
<TableCaption />
) : (
<caption>Student Record</caption>
)}
<TableHead />
<TableBody />
<TableFooter />
</table>
</DataProvider>
</main>
);
};

export default App;

The trick here is to pull in the configcat-react library in order to retrieve the value of the feature flag. The library uses a hook called "useFeatureFlag" to do this.

The hook takes three arguments:

  • the name of the feature flag
  • a default flag value
  • and in this case, a hard-coded object that represents the user

The email of the user is used to evaluate the flag value. The result will then determine whether to display the "TableCaption" component or a simple caption element in a conditional statement.

That's it, run the application with npm run dev.

stundents app with feature flags photo

Creating the feature flag with LaunchDarkly

  1. Sign in to the LaunchDarkly Dashboard
  2. In the dashboard, create a feature flag and fill in the following details:
    • Name: captionCounterFlag
    • Key: captionCounterFlag
    • Check the Client-side SDK availability with SDKs using Client-side ID
    • Flag Variations: Boolean
    • Default Variations: On = true and Off = false
    • Save the flag

launchdarkly flag setup photo

  1. Select the targeting tab
    • Switch the targeting toggle to ON
    • Click on the +Add rules button
    • Add the following rules:
      • if email contains @it.campus.com
      • serve true
    • Default rule:
      • serve false
    • Click on the Review and save button and the Save changes button

launchdarkly-flag-setup-photo

  1. To obtain the SDK key, press "Cmd + K" on a Mac or "Ctrl + K" on Windows. Choose the option Copy SDK Key for the Current Environment, then select the Client Side ID option.

launchdarkly sdk key photo

Accessing the LaunchDarkly feature flag from the application

For the LaunchDarkly implementation, the "main.jsx" component will be reverted to the starting condition. Remove all elements connecting the application to ConfigCat.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);

Setting up the feature flag in the project has a few steps:

  1. To install the LaunchDarkly SDK for React, run the following command:
npm i launchdarkly-react-client-sdk
  1. In the App component import the withLDProvider from launchdarkly-react-client-sdk
  2. Bring in the useFlags hook which will help to evaluate the flag value.
  3. At the bottom of the component's export default, import the withLDProvider to wrap the application with the LaunchDarkly provider. This is also where the user object is set, providing the email value necessary for evaluating the flag.
  4. In the clientSideID add the SDK key, which was mentioned in the previous section.
  5. Deconstruct the "captionCounterFlag" flag from useFlags hook to conditionally render between the new "TableCaption", and the old <caption>Student List</caption> component.
import { withLDProvider, useFlags } from "launchdarkly-react-client-sdk";
import { DataProvider } from "./context/DataContext";
import TableHead from "./components/TableHead";
import TableBody from "./components/TableBody";
import TableFooter from "./components/TableFooter";
import TableCaption from "./components/TableCaption";

const App = () => {
const { captionCounterFlag } = useFlags();
return (
<main>
<DataProvider>
<table>
{captionCounterFlag ? (
<TableCaption captionCounterFlag={captionCounterFlag} />
) : (
<caption>Student Record</caption>
)}
<TableHead />
<TableBody />
<TableFooter />
</table>
</DataProvider>
</main>
);
};

export default withLDProvider({
clientSideID: "YOUR-SDK-KEY",
context: {
type: "user",
key: "USER-ID",
email: "[email protected]",
},
})(App);

In the feature flag implementation using the LaunchDarkly SDK, the value of the flag is retrieved using the useFlags hook. The hook returns an object that has the value of the feature flag as a property. The feature flag value is then used to conditionaly render eather the "TableCaption" component or the caption element.

  • withLDProvider is a higher-order component importing the LaunchDarkly library, and it is used to provide the App component with the necessary context and functionality to interact with the LaunchDarkly service.

  • useFlags is a custom hook that retrieves all feature flags. It uses the useContext primitive to access the LaunchDarkly context established by withLDProvider.

That's it, run the application with npm run dev. The application should behave the same way as it did with the ConfigCat implementation.

Summary of key differences

In the ConfigCat implementation, the useFeatureFlag hook is used to retrieve the feature flag value and render either "TableCaption" or a plain caption element.

The LaunchDarkly implementation uses the useFlags hook and accesses the feature flag as a property, which is later used as a value to render either "TableCaption" component or a plain "caption" element.

With ConfigCat, the App component is exported directly, and the application is wrapped with the SDK in the "main.jsx" file. With LaunchDarkly, the App component is exported wrapped in the withLDProvider higher-order component, which sets up LaunchDarkly.

I would like to mention some pros and cons of implementing feature flags on the client-side:

Pros:

  • Easy to implement, especially if it's a small feature
  • Easy to maintain component-level isolation, allowing changes to be made and tested independently.
  • Easy to track and manage, as the flags are within the component code.

Cons:

  • Improper implementation can lead to cluttered code and become difficult to manage as the application grows.
  • Can be error-prone and require more testing.

The one important thing to take away is to keep the component decoupled from the rest of the application, and completely contained under the influence of the feature flag.

Overview of Feature Flag Services

When it comes to choosing a feature flag service, ConfigCat stands out with its forever free plan and fixed prices across five different pricing tiers. This means that users can enjoy all the benefits of the service without worrying about unexpected costs. ConfigCat offers client-side feature flag reads ranging from 5 million in the free plan to over 6+ billion per month in their Dedicated plan, offering options in between to fit different needs and usage levels. Another advantage of ConfigCat is its unlimited team size feature, allowing for seamless collaboration among team members without incurring additional charges. This makes it a great choice for teams of all sizes.

On the other hand, LaunchDarkly only offers three paid plans, and a 14-day trial period. Their client-side feature flag reads are based on the chosen plan and can range from 1,000 in the Starter Plan, to a custom amount agreed through LaunchDarkly sales in the Enterprise plan. While this customization is great if you have a specific feature flag read requirement in mind, it also means that your costs may fluctuate based on usage. The team size is charged per seat[^1], so larger teams may face increased costs. This could be a challenge for organizations with many team members, as they may need to allocate a significant budget to using the service.

[^1] Each team member who logs in with a unique email address counts as a seat.

Conclusion

Both ConfigCat and LaunchDarkly are feature flag services that are user-friendly, even non-technical users will find them easy to use. We saw this by using their support for email targeting, which allows you to target specific groups of users based on their email formats.

As a final note, we saw that utilizing feature flags saves time and ultimately makes your development process more efficient, allowing tests on the live application while controlling the acceptability of the new feature. Both ConfigCat and LaunchDarkly deliver excellent tools. The decision of whom to work with is ultimately up to you - ConfigCat or LaunchDarkly?

To see more awesome posts like this and other announcements, follow ConfigCat on Twitter, Facebook, LinkedIn, and GitHub.