Feature Gates

A feature gate is a high level tool to turn features on and off. It provides metadata about features, a simple, opinionated API, and avoid many potential pitfalls of other systems, such as using preferences directly. It is designed to be compatible with tools that want to know and affect the state of features in Firefox over time and in the wild.

Feature Definitions

All features must have a definition, specified in toolkit/components/featuregates/Features.toml. These definitions include data such as title and description (to be shown to users), and bug numbers (to track the development of the feature over time). Here is an example feature definition with an id of demo-feature:

[demo-feature]
title = "Demo Feature"
description = "A no-op feature to demo the feature gate system."
restart-required = false
bug-numbers = [1479127]
type = boolean
is-public = {default = false, nightly = true}
default-value = {default = false, nightly = true}

Targeted values

Several fields can take a value that indicates it varies by channel and OS. These are known as targeted values. The simplest computed value is to simply provide the value:

default-value: true

A more interesting example is to make a feature default to true on Nightly, but be disabled otherwise. That would look like this:

default-value: {default: false, nightly: true}

Values can depend on multiple conditions. For example, to enable a feature only on Nightly running on Windows:

default-value: {default: false, "nightly,win": true}

Multiple sets of conditions can be specified, however use caution here: if multiple sets could match (except default), the set chosen is undefined. An example of safely using multiple conditions:

default-value: {default: false, nightly: true, "beta,win": true}

The default condition is required. It is used as a fallback in case no more-specific case matches. The conditions allowed are

  • default
  • release
  • beta
  • dev-edition
  • nightly
  • esr
  • win
  • mac
  • linux
  • android

Fields

title
Required. A human readable name for the feature, meant to be shown to users. Should fit onto a single line.
description
Required. A human readable description for the feature, meant to be shown to users. Should be at most a paragraph.
bug-numbers
Required. A list of bug numbers related to this feature. This should likely be the metabug for the the feature, but any related bugs can be included. At least one bug is required.
restart-required
Required. If this feature requires a the browser to be restarted for changes to take effect, this field should be true. Otherwise, the field should be false. Features should aspire to not require restarts and react to changes to the preference dynamically.
type
Required. The type of value this feature relates to. The only legal value is boolean, but more may be added in the future.
preference
Optional. The preference used to track the feature. If a preference is not provided, one will be automatically generated based on the feature ID. It is not recommended to specify a preference directly, except to integrate with older code. In the future, alternate storage mechanisms may be used if a preference is not supplied.
default-value
Optional. This is a targeted value describing the value for the feature if no other changes have been made, such as in a fresh profile. If not provided, the default for a boolean type feature gate will be false for all profiles.
is-public
Optional. This is a targeted value describing on which branches this feature should be exposed to users. When a feature is made public, it may show up in a future UI that allows users to opt-in to experimental features. This is not related to about:preferences or about:config. If not provided, the default is to make a feature private for all channels.

Feature Gate API

class FeatureGate()

A high level control for turning features on and off.

FeatureGate.addObserver(id, observer, testDefinitionsUrl)

Add an observer for a feature gate by ID. If the feature is of type boolean and currently enabled, onEnable will be called.

The underlying feature gate instance will be shared with all other callers of this function, and share an observer.

Arguments:
  • id (string) – The ID of the feature’s definition in Features.toml.
  • observer (object) – Functions to be called when the feature changes. All observer functions are optional.
  • observer.onEnable (function) – Called when the feature becomes enabled.
  • observer.onDisable (function) – Called when the feature becomes disabled.
  • observer.onChange (function) – Called when the feature’s state changes to any value. The new value will be passed to the function.
  • testDefinitionsUrl (string) – A URL from which definitions can be fetched. Only use this in tests.
Returns:

Promise.<boolean> – The current value of the feature.

FeatureGate.removeObserver(id, observer)

Remove an observer of changes from this feature

Arguments:
  • id (string) – The ID of the feature’s definition in Features.toml.
  • observer – Then observer that was passed to addObserver to remove.
FeatureGate.isEnabled(id, testDefinitionsUrl)

An alias of getValue for boolean typed feature gates.

Arguments:
  • id (string) – The ID of the feature’s definition in Features.toml.
Throws:

Error – If the feature is not a boolean.

Returns:

Promise.<boolean> – A promise for the value associated with this feature.

FeatureGate.fromId(id, testDefinitionsUrl)

Constructs a feature gate object that is defined in Features.toml. This is the primary way to create a FeatureGate.

Arguments:
  • id (string) – The ID of the feature’s definition in Features.toml.
  • testDefinitionsUrl (string) – A URL from which definitions can be fetched. Only use this in tests.
Throws:

If the id passed is not defined in Features.toml.

class FeatureGateImplementation(definition)

An individual feature gate that can be re-used for more advanced usage.

Feature implementors should use the methods fromId(), addListener(), removeListener() and removeAllListeners(). Additionally, metadata is available for UI and analysis.

FeatureGateImplementation.id

A short string used to refer to this feature in code.

FeatureGateImplementation.title

A short, descriptive string to identify this feature to users.

FeatureGateImplementation.description

A longer string to show to users that explains the feature.

FeatureGateImplementation.type

The type of feature. Currently only booleans are supported. This may be richer than JS types in the future, such as enum values.

FeatureGateImplementation.bugNumbers

Bug numbers associated with this feature.

FeatureGateImplementation.isPublic

If this feature should be exposed to users in an advanced settings panel for this build of Firefox.

FeatureGateImplementation.defaultValue

The default value for the feature gate for this update channel.

FeatureGateImplementation.restartRequired

Whether this feature requires a browser restart to take effect after toggling.

FeatureGateImplementation.preference

The name of the preference that stores the value of this feature.

This preference should not be read directly, but instead its values should be accessed via FeatureGate#addObserver or FeatureGate#getValue. This property is provided for backwards compatibility.

FeatureGateImplementation.addObserver(observer)

Add an observer for changes to this feature. When the observer is added, onChange will asynchronously be called with the current value of the preference. If the feature is of type boolean and currently enabled, onEnable will additionally be called.

Arguments:
  • observer (object) – Functions to be called when the feature changes. All observer functions are optional.
  • observer.onEnable (function) – Called when the feature becomes enabled.
  • observer.onDisable (function) – Called when the feature becomes disabled.

:param : :returns: Promise.<boolean> – The current value of the feature.

FeatureGateImplementation.removeObserver(observer)

Remove an observer of changes from this feature

Arguments:
  • observer – The observer that was passed to addObserver to remove.
FeatureGateImplementation.removeAllObservers()

Removes all observers from this instance of the feature gate.

FeatureGateImplementation.getValue()

Get the current value of this feature gate. Implementors should avoid storing the result to avoid missing changes to the feature’s value. Consider using addObserver() if it is necessary to store the value of the feature.

Returns:Promise.<boolean> – A promise for the value associated with this feature.
FeatureGateImplementation.isEnabled()

An alias of getValue for boolean typed feature gates.

Throws:Error – If the feature is not a boolean.
Returns:Promise.<boolean> – A promise for the value associated with this feature.