Implementing release toggles with React & CLI

14 April 2019 by Appknobs

Angular developer? Check out our adding release flags to Angular guide!

Let's add a release toggle

When you're doing trunk-based development whatever is in your main branch - usually master - is pushed to production. At the same time you might want to use short-lived feature branches, add small improvements at a time and integrate (merge) often. To prevent half-finished features appearing in production you will want to use release toggles. These toggles - also known as release flags - will allow you to deploy, demo and end-to-end test a feature under development by select users but keep it hidden from anyone else.

It is a very simple concept but comes with a few difficulties if you try to implement it from scratch. Hence we're going to use two open source NPM packages from Appknobs to get the job done super fast: @appknobs/react for the UI and @appknobs/cli for the command line.

💡TIP: Read our guide on the challenges of bespoke solutions and buy-vs-build

Create a new project (optional)

We assume you have a working React 16+ app ready for a new release toggle. If you need a quick sandbox, generate one using

npx create-react-app my-sandbox

or

yarn create react-app my-sandbox

Install dependencies

In your project's folder, install @appknobs/react, @appknobs/client and @appknobs/cli:

npm install @appknobs/react @appknobs/client && npm install -D @appknobs/cli

or

yarn add @appknobs/react @appknobs/client && yarn add -D @appknobs/cli

Add a release toggle

@appknobs/react comes with a declarative feature toggle component called Feature. After you wrap a section of your application in <Feature name='...'><YourSection /></Feature> it becomes a managed feature and so you can toggle the release without code changes.

It's up to you to select a part of your UI to hide behind a toggle. If you're using the sandbox generated with Create React App, open src/App.js and change it to

import React, { Component } from 'react';
import {Feature} from '@appknobs/react'
import logo from './logo.svg'
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />

          {/* This is our super-simple feature: */}
          <Feature name='sandbox-yay'>
            <h1>Yay, I'm using release toggles!</h1>
          </Feature>

        </header>
      </div>
    );
  }
}

export default App;

This code hides <h1>Yay, I'm using release toggles!</h1> behind a release toggle. Yes, it's a bit simplistic, but works nicely as an example. The Feature component can wrap any part of your UI hierarchy and supports render props for more complex scenarios. Please note once a feature is managed it is hidden by default. So your "Yay" won't show up just yet.

Feature flag autodiscovery

Use @appknobs/cli - the command line interface to Appknobs - to let the feature management service know about your release flag. With Yarn you can simply run yarn knobs to invoke it, otherwise, add a line to your package.json...

  "scripts": {
    "knobs": "knobs"
  }

… and run npm run knobs. Installing @appknobs/cli as a global package or running npx @appknobs/cli also works. For the examples below we assume it's a global package.

To make your life easier, Appknobs can look at your codebase, find & register all feature flags automatically. No need to manually copy-paste.

Invoke knobs parse src/ from the top level of your project and the tool will guide you through the process:

$ knobs parse src

You need to log in before you can upload feature flags from your project

? Would you like to log in or register now? …
  Log in
❯ Register
  Quit

Basically, you need to select Register, enter your email and a password, press enter:

App name: my-sandbox
App ID: DfXPWwujs4YxZc2~Ay8~9
Framework: react

Found the following feature flags:
👉 sandbox-yay

👍 sandbox-yay saved

That's it 👏

Your release toggles are discovered and recorded in the Appknobs service automagically.

Get your App ID

Please note your App ID as you'll need it soon. To find it later, run the following command:

$ knobs app-info

✔ App name: my-app-xxx
✔ appID: TfXPWwiysHYxZc2~Ay8~9

Get your API key

You will need an API key to access Appknobs services from your app.

CLI is at your service again:

$ knobs apikey

✔ Your API key is: 62zYKyPePbmPqxpPoYAcm and is valid until Mon May 13 2019

💡TIP: You can always go to our web console at https://console.appknobs.io/ to find this information.

Wrap your app in <Appknobs>

To ensure each feature toggle "flips" when needed, we provide a wrapper component that propagates changes using the React context. It is similar to the high-level components Redux or React Router provide.

This is also the place to configure and inject the service client that will fetch the available feature toggles of your app at runtime. You will need your appId and the apiKey from before.

Finally, you send the runtime context - e.g. username, hostname, cookie values, etc. - to the service to make the decision on features. The content of the context payload is 100% up to you. The following example is quite trivial but works for now and allows you to keep experimenting. Find out more about the payload and conditions in our previous blog post.

💡TIP: Check out the @appknobs/react and @appknobs/client documentation to learn about advanced topics or take a look at our code examples for React/Next.js, React Native and other environments in the appknobs/appknobs-examples repo.

For the CRA sandbox example, the src/index.js needs to be changed like this:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Appknobs} from '@appknobs/react'
import {newBrowserClient} from '@appknobs/client'

// Create a service client that will work in a browser:
const client = newBrowserClient({appId: 'YOUR_APP_ID', apiKey: 'YOUR_API_KEY'})

// Pass the client and a simple payload to the Apknobs wrapper:
ReactDOM.render(<Appknobs client={client} payload={{user: 'me'}}><App /></Appknobs>, document.getElementById('root'));

serviceWorker.unregister();

Note: you need to use <Appknobs> only once then add as many Features as you like!

Your code is ready

As mentioned before, the thinking behind release toggles is that you can change the visibility of a feature without code changes. Since the "Yay" feature is now managed, let's head over to the web console at https://console.appknobs.io/ and set the conditions.

💡TIP: knobs console will open the web UI

There is a detailed guide to the web console which you can refer to if needed. The steps are quite simple:

  • Visit https://console.appknobs.io/
  • Log in with your username and password
  • Under your app - "my-sandbox" in our example - click Edit features
  • Under the feature you've defined click Edit conditions

In the condition form, let's add:

  • user as property
  • Equal to as predicate
  • me as argument

— and save.

Done

Reload your app and enjoy your "Yay" message! 🥇

yay feature visible

Try setting the context payload in src/index.js to something else, e.g. {user: 'Poirot'} and see what happens.

✋Note: evaluation is cached for 1 minute by the payload, so changes made on the Console might take a few seconds to be visible in the app.

Hopefully this guide allows you to get started on a more productive, trunk based development journey using release toggles. Please share if you liked it or let us know if we missed something!

Appknobs is feature flags without the work
Read our blog, Twitter and newsletter for tips, updates, tutorials and articles.