Feature Toggles in React.JS applications

About the speaker

Daniel de la Cruz

  • +10 years of experience developing web applications
  • Speaks JS and C#
  • Currently working as a Tech Lead at Typeform.com
  • Likes to play video games

Feature Toggle

A feature toggle is a technique for allowing a team to modify a system behaviour without modifying code 
function calculationAlgorithm() {
    // current implementation lives here
}
function calculationAlgorithm() {
    const useNewAlgorithm = false
    // const useNewAlgorithm = true // UNCOMMENT TO WORK WITH THE NEW ALGORITHM

    if (useNewAlgorithm) {
        enhancedCalculationAlgorithm()
    } else {
        currentCalculationAlgorithm()
    }
}

function enhancedCalculationAlgorithm() {
    // new implementation lives here
}

function currentCalculationAlgorithm() {
    // current implementation lives here
}

after

before

function calculationAlgorithm() {
    if (featureIsEnabled('use-new-calculation-algorithm')) {
        enhancedCalculationAlgorithm()
    } else {
        currentCalculationAlgorithm()
    }
}

Dynamic Feature Toggles

function createToggleRouter(featureConfig){
  return {
    setFeature(featureName,isEnabled){
      featureConfig[featureName] = isEnabled
    },
    featureIsEnabled(featureName){
      return featureConfig[featureName]
    }
  }
}

Toggle Router

Inspiration

When should I use Feature Toggles?

... and why should I use them?

A/B testing

vs

Canary releasing

Challenges

#1

How to implement Feature toggles in a SPA?

#2

How to keep my code clean?

#3

How do I make feature toggles work in Universal Apps?

A Universal Javascript library to help you implement feature toggles 

Library features

  1. Component hierarchy agnostic about feature toggles
  2. No branching in production code
  3. Supports Universal environments with server-side rendering

Usage

#1 Create your component and its variations

const Card = ({title, subtitle}) => (
  <div className='card'>
    <div className='card-title'>
      {title}
    </div>
    <p className='card-subtitle'>
      {subtitle}
    </p>
    <div className='card-action'>
      <a href='#'>This is a link</a>
    </div>
  </div>
)

#2 Organize your code to be maintainable

├── Card
│   ├── index.js
│   ├── Card-Default
│   │   └── index.js
│   ├── Card-Variation-A
│   │   └── index.js
│   └── Card-Variation-B
│       └── index.js

#3 Wrap your component with ToggleComponent

import { ToggleComponent } from 'react-feature-toggle'
import CardVariationA from './Card-Variation-A'
import CardVariationB from './Card-Variation-B'
import CardDefault from './Card-Default'

export default ToggleComponent(CardDefault, CardVariationA, CardVariationB)

#4 Use your component normally

import Card from './Card'

const CardList = () => (
  <div className='card-list'>
    <Card title='First Card' subtitle='the first card description'/>
    <Card title='Second Card' subtitle='the second card description' />
    <Card title='Third Card' subtitle='the third card description' />
    <Card title='Fourth Card' subtitle='the fourth card description' />
  </div>
)

#5 Define your experiments

{
    experiments: [{
      Card: {
        variations: [{
          name: 'Card'
        }, {
          name: 'Card-Variation-A',
          force: false,
          props: {
            title: 'Toggled title'
          }
        }, {
          name: 'Card-Variation-B'
        }]
      },

      ...
    ]
}

#6 Create a strategy* to decide the toggle

const toggles = experiments
  .map(e => strategy(e))
  .reduce(reducer)

/* console.log(toggles)
{
  CardVariationA: {
    props: {
      title: 'Variation A title'
    }
  }
}
*/

#7 Wrap your application with ToggleApp

import { ToggleApp } from 'react-feature-toggle'

const MyToggledApp = ToggleApp(MyApp, toggles)

ReactDom.render(<MyToggledApp />, document.getElementById('main'))

*About strategies

A strategy is something that only you can implement to decide which variation should be shown to the user, depending on the feature and your use case.

Some possible strategies could be based on:

  • A random number (Using a UUID)
  • Percentage (Only to 5% of my users...)
  • User profile (Only registered, well-known...)
  • IP/User agent (Only iOS from San Francisco...)
  • ...

Universal apps

Server-side rendering

import {Universal} from 'react-feature-toggle'

...

let markup = YourApp.renderToString();
markup = Universal.injectIntoMarkup({
  markup,
  toggles,
  name: 'cardToggles'
})

Resulting markup

<script>
    window.cardToggles={CardVariationA:{props:{title:'Variation A title'}}};
</script>

Client side

import { ToggleApp } from 'react-feature-toggle'

const MyToggledApp = ToggleApp(MyApp, toggles)

ReactDom.render(<MyToggledApp />, window.cardToggles)

How does it work?

Higher

Order

Components

ToggleApp

Assigns the toggles object to the application context, creating a new copy and returning the wrapped component

ToggleComponent

  • Reads from the context the feature toggles object and checks if one of the variations matches with the provided toggle's name.
  • If so, assigns the toggle's props to the variation component's props
  • If not, returns the default one

That's pretty much it!

Questions?

Thank you!

Feature Toggles in React applications

By Daniel de la Cruz Calvo

Feature Toggles in React applications

This talks describes the feature toggle technique, applied in Single Page Applications built with React.JS

  • 2,419