|
| 1 | +--- |
| 2 | +id: desktop-feature-manifest |
| 3 | +title: Feature Manifest Reference |
| 4 | +slug: /platform-guides/desktop/feature-manifest |
| 5 | +--- |
| 6 | + |
| 7 | +# Desktop Feature Manifest Reference |
| 8 | + |
| 9 | +The desktop Nimbus Feature Manifest ([`FeatureManifest.yaml`](https://searchfox.org/mozilla-central/source/toolkit/components/nimbus/FeatureManifest.yaml)) defines every feature that can be configured by experiments and rollouts in Firefox Desktop. Each feature entry declares what variables it exposes, if those variables connect to Firefox prefs, and whether the feature supports exposure telemetry. |
| 10 | + |
| 11 | +After adding or modifying a feature in the manifest, a build step is required to update the generated header file. |
| 12 | + |
| 13 | +:::tip |
| 14 | +This reference covers the **Desktop** manifest format (`FeatureManifest.yaml`). For mobile apps, see the [Feature Manifest Language (FML) specification](/technical-reference/fml/fml-spec). |
| 15 | +::: |
| 16 | + |
| 17 | +## Feature properties |
| 18 | + |
| 19 | +Each top-level key in `FeatureManifest.yaml` is a feature ID. The feature definition supports these properties: |
| 20 | + |
| 21 | +| Property | Required | Type | Default | Description | |
| 22 | +| :--- | :---: | :--- | :--- | :--- | |
| 23 | +| `description` | Yes | string | — | Human-readable description of the feature | |
| 24 | +| `owner` | Yes | string | — | Email of the team or person responsible | |
| 25 | +| `hasExposure` | Yes | boolean | — | Whether this feature records [exposure events](/data-analysis/jetstream/overview#enrollment-vs-exposure) | |
| 26 | +| `exposureDescription` | If `hasExposure: true` | string | — | Describes when/how the exposure event fires | |
| 27 | +| `variables` | Yes | object | — | Variable definitions (can be `{}` if the feature has no variables) | |
| 28 | +| `isEarlyStartup` | No | boolean | `false` | Cache values in Firefox prefs for synchronous access during early startup | |
| 29 | +| `allowCoenrollment` | No | boolean | `false` | Allow multiple simultaneous experiment/rollout enrollments for this feature | |
| 30 | +| `applications` | No | string[] | `["firefox-desktop"]` | Which Firefox processes can enroll (see [Applications](#applications)) | |
| 31 | +| `schema` | No | object | — | JSON Schema for validation (see [Schema validation](#schema-validation)) | |
| 32 | + |
| 33 | +### Applications |
| 34 | + |
| 35 | +The `applications` array specifies which Firefox processes can use this feature: |
| 36 | + |
| 37 | +- `"firefox-desktop"` — the main browser process (default) |
| 38 | +- `"firefox-desktop-background-task"` — the background task runner |
| 39 | + |
| 40 | +```yaml |
| 41 | +applications: |
| 42 | + - firefox-desktop |
| 43 | + - firefox-desktop-background-task |
| 44 | +``` |
| 45 | +
|
| 46 | +If omitted, defaults to `["firefox-desktop"]`. |
| 47 | + |
| 48 | +### Schema validation |
| 49 | + |
| 50 | +The optional `schema` property points to a JSON Schema file that validates the combined feature configuration. It has two fields: |
| 51 | + |
| 52 | +- `uri` — a `resource://` or `moz-src://` URI that Firefox loads at runtime for client-side validation |
| 53 | +- `path` — a filesystem path (relative to the repository root) where Experimenter can find the schema |
| 54 | + |
| 55 | +```yaml |
| 56 | +schema: |
| 57 | + uri: resource://nimbus/schemas/PrefFlipsFeature.schema.json |
| 58 | + path: toolkit/components/nimbus/schemas/PrefFlipsFeature.schema.json |
| 59 | +``` |
| 60 | + |
| 61 | +## Variable properties |
| 62 | + |
| 63 | +Each key under `variables` defines a configurable variable. Variables support these properties: |
| 64 | + |
| 65 | +| Property | Required | Type | Description | |
| 66 | +| :--- | :---: | :--- | :--- | |
| 67 | +| `description` | Yes | string | Human-readable description of the variable | |
| 68 | +| `type` | Yes | string | One of `boolean`, `string`, `int`, `json` | |
| 69 | +| `fallbackPref` | No | string | Pref to read the default value from (mutually exclusive with `setPref`) | |
| 70 | +| `setPref` | No | string or object | Pref that Nimbus actively sets on enrollment (mutually exclusive with `fallbackPref`) | |
| 71 | +| `enum` | No | array | Constrains allowed values (`string` and `int` types only) | |
| 72 | + |
| 73 | +### Variable types |
| 74 | + |
| 75 | +| Type | Values | Supports `enum` | Notes | |
| 76 | +| :--- | :--- | :---: | :--- | |
| 77 | +| `boolean` | `true` / `false` | No | | |
| 78 | +| `string` | Text values | Yes | | |
| 79 | +| `int` | Whole numbers | Yes | | |
| 80 | +| `json` | Arbitrary JSON objects/arrays | No | Stored as stringified JSON if connected to a pref | |
| 81 | + |
| 82 | +:::note |
| 83 | +There is no `float` type. If you need floating-point values, use `string` and parse the value in your code. |
| 84 | +::: |
| 85 | + |
| 86 | +### `fallbackPref` vs `setPref` |
| 87 | + |
| 88 | +These are **mutually exclusive** — a variable can use one or the other, not both. |
| 89 | + |
| 90 | +| | `fallbackPref` | `setPref` | |
| 91 | +| :--- | :--- | :--- | |
| 92 | +| **What it does** | Reads the current pref value as the default when no experiment is active | Nimbus actively **sets** the pref when the user enrolls | |
| 93 | +| **On enrollment** | No change to the pref | Pref is set to the experiment branch value | |
| 94 | +| **On unenrollment** | No change to the pref | Original pref value is restored | |
| 95 | +| **If user changes pref** | No effect on enrollment | Causes automatic unenrollment | |
| 96 | +| **Use case** | Feature gates and defaults that already exist as browser prefs | Controlling prefs that other code reads directly | |
| 97 | + |
| 98 | +**`fallbackPref` example:** |
| 99 | +```yaml |
| 100 | +enabled: |
| 101 | + type: boolean |
| 102 | + fallbackPref: browser.aboutwelcome.enabled |
| 103 | + description: Whether the about:welcome page is enabled |
| 104 | +``` |
| 105 | + |
| 106 | +**`setPref` example:** |
| 107 | +```yaml |
| 108 | +enabled: |
| 109 | + type: boolean |
| 110 | + setPref: |
| 111 | + branch: default # or "user" |
| 112 | + pref: browser.search.visualSearch.featureGate |
| 113 | + description: Feature gate for visual search |
| 114 | +``` |
| 115 | + |
| 116 | +The `setPref` object format has two fields: |
| 117 | +- `branch` — which pref branch to set: `"default"` (resets each startup) or `"user"` (persists to disk) |
| 118 | +- `pref` — the pref name |
| 119 | + |
| 120 | +:::note |
| 121 | +For a deep dive into pref experiment behavior including unenrollment scenarios, pref branch trade-offs, and conflict handling, see [Pref Experiments](/platform-guides/desktop/pref-experiments). |
| 122 | +::: |
| 123 | + |
| 124 | +### `enum` constraints |
| 125 | + |
| 126 | +The `enum` property restricts a `string` or `int` variable to a fixed set of values: |
| 127 | + |
| 128 | +```yaml |
| 129 | +rankingMode: |
| 130 | + type: string |
| 131 | + enum: |
| 132 | + - default |
| 133 | + - interest |
| 134 | + - random |
| 135 | + description: The ranking algorithm to use |
| 136 | +``` |
| 137 | + |
| 138 | +## Examples |
| 139 | + |
| 140 | +### Simple feature with a feature gate |
| 141 | + |
| 142 | +```yaml |
| 143 | +search: |
| 144 | + description: Search service related features |
| 145 | + owner: search-and-suggest-program@mozilla.com |
| 146 | + hasExposure: true |
| 147 | + exposureDescription: > |
| 148 | + Recorded when the visual search context menu item is shown. |
| 149 | + variables: |
| 150 | + visualSearchEnabled: |
| 151 | + type: boolean |
| 152 | + setPref: |
| 153 | + branch: default |
| 154 | + pref: browser.search.visualSearch.featureGate |
| 155 | + description: Feature gate for visual search |
| 156 | +``` |
| 157 | + |
| 158 | +### Feature with multiple variable types |
| 159 | + |
| 160 | +```yaml |
| 161 | +urlbar: |
| 162 | + description: The Address Bar |
| 163 | + owner: search-and-suggest-program@mozilla.com |
| 164 | + hasExposure: true |
| 165 | + exposureDescription: > |
| 166 | + Recorded once per session on first urlbar interaction. |
| 167 | + variables: |
| 168 | + onboardingTimesToShow: |
| 169 | + type: int |
| 170 | + fallbackPref: browser.urlbar.quickactions.timesToShowOnboardingLabel |
| 171 | + description: Number of times to show the onboarding label |
| 172 | + quickSuggestRankingMode: |
| 173 | + type: string |
| 174 | + fallbackPref: browser.urlbar.quicksuggest.rankingMode |
| 175 | + enum: |
| 176 | + - default |
| 177 | + - interest |
| 178 | + - random |
| 179 | + description: The ranking mode for QuickSuggest |
| 180 | + scoreMap: |
| 181 | + type: json |
| 182 | + description: JSON object mapping result types to scores |
| 183 | +``` |
| 184 | + |
| 185 | +### Early startup feature |
| 186 | + |
| 187 | +```yaml |
| 188 | +aboutwelcome: |
| 189 | + description: The about:welcome page |
| 190 | + owner: omc-core@mozilla.com |
| 191 | + hasExposure: true |
| 192 | + exposureDescription: > |
| 193 | + Recorded once per session when about:welcome is shown. |
| 194 | + isEarlyStartup: true |
| 195 | + variables: |
| 196 | + enabled: |
| 197 | + type: boolean |
| 198 | + fallbackPref: browser.aboutwelcome.enabled |
| 199 | + description: Whether the about:welcome page is enabled |
| 200 | + screens: |
| 201 | + type: json |
| 202 | + fallbackPref: browser.aboutwelcome.screens |
| 203 | + description: Content to show in the onboarding flow |
| 204 | +``` |
| 205 | + |
| 206 | +### Co-enrolling feature |
| 207 | + |
| 208 | +```yaml |
| 209 | +prefFlips: |
| 210 | + description: Flip arbitrary prefs for incident response |
| 211 | + owner: beth@mozilla.com |
| 212 | + hasExposure: false |
| 213 | + allowCoenrollment: true |
| 214 | + variables: |
| 215 | + prefs: |
| 216 | + type: json |
| 217 | + description: The prefs to set |
| 218 | + schema: |
| 219 | + uri: resource://nimbus/schemas/PrefFlipsFeature.schema.json |
| 220 | + path: toolkit/components/nimbus/schemas/PrefFlipsFeature.schema.json |
| 221 | +``` |
| 222 | + |
| 223 | +## Further reading |
| 224 | + |
| 225 | +- [Feature API Reference](/platform-guides/desktop/feature-api) — how to access feature values in code |
| 226 | +- [Pref Experiments](/platform-guides/desktop/pref-experiments) — deep dive into `setPref` and `fallbackPref` behavior |
| 227 | +- [Co-enrolling Features](/technical-reference/fml/coenrolling-features) — how `allowCoenrollment` works |
| 228 | +- [FeatureManifest.yaml on Searchfox](https://searchfox.org/mozilla-central/source/toolkit/components/nimbus/FeatureManifest.yaml) — the live manifest |
0 commit comments