Getting started
Quick start
Build the checkout feature from the introduction, enabled for everyone in the Netherlands and a quarter of everyone else, and a supportEmail variable to configure it. You will define both, build a datafile and evaluate them with the SDK, all on your machine.
Prerequisites#
- Node.js >= 24.0.0
Create a project#
Run these commands in an empty directory:
npx @featurevisor/cli@latest initnpm installIf any entries would be overwritten, init stops and lists them. The scaffold is already a working project. This is how it looks once you add the feature and the variable in this guide:
featurevisor.config.jsproject configurationattributes/values your application passes incountry.ymldeviceId.ymluserId.yml
segments/named audiences built on attributesnetherlands.yml
features/flags, variations and variablescheckout.ymlwe will add it latershowCookieBanner.yml
variables/typed configurationsupportEmail.ymlwe will add it later
targets/what each datafile containsall.yml
Keep the project in its own repository, separate from your applications. See Projects.
Bring your AI agent#
Featurevisor has a skill for AI coding agents such as Claude Code, Codex, Cursor and OpenCode. With it, your agent can write the definitions in this guide, run the CLI and explain the results.
npx skills add featurevisor/featurevisorThen ask your agent to write the feature and the variable in this guide for you:
/featurevisor create a checkout feature that is enabled for users in the Netherlands and 25% of everyone else, and a supportEmail variable that is [email protected] for users in the Netherlands and [email protected] for everyone else
Review what it writes, as you would a colleague's pull request. You can also follow the steps by hand. Skills for AI agents lists more you can ask, from rollouts to debugging an evaluation.
Describe your users#
When your application asks for a value, it passes facts about the user, such as their ID and country. This is the context, and attributes declare what it can contain. The scaffold already declares three. This one is country:
description: Countrytype: stringuserId and deviceId are declared the same way. Featurevisor checks every condition and bucketBy against these declarations, so a misspelled attribute fails before anything ships. See Attributes.
Name an audience#
A segment names a group of users through conditions on attributes. The scaffold's netherlands segment matches every context whose country is nl:
description: The Netherlandsconditions: - attribute: country operator: equals value: nlFeatures and variables refer to a segment by its key, so the audience is defined once. The next two steps both use netherlands. See Segments.
Define a feature#
Create features/checkout.yml:
description: Checkout redesignbucketBy: userIdrules: - key: netherlands conditions: netherlands percentage: 100 - key: everyone conditions: '*' percentage: 25Rules are checked in order, and the first rule whose conditions match the context decides. The netherlands rule uses the segment from the previous step, and '*' matches every context. bucketBy: userId uses the userId attribute to keep each user's answer stable as you change the percentage. See Features.
Define a variable#
A flag answers whether something is on. A variable answers with a value, such as a support address, a price or a limit. Create variables/supportEmail.yml:
description: Support email shown in checkouttype: stringoverrides: - key: netherlands conditions: netherlandsEveryone gets the default, and the first matching override replaces it. The same netherlands segment now drives a flag and a value. Change the address in a pull request, and your applications use it once they load the next datafile, without a new release. Variables can also hold numbers, booleans, objects and arrays, all checked against their type. See Variables.
Build datafiles#
Datafiles are the static JSON your applications load. Build them from your definitions:
npx featurevisor buildTarget: all ✔ datafiles/featurevisor-all.jsonDatafiles builtThe scaffold's targets/all.yml has no selectors, so its datafile contains every feature and variable, including checkout and supportEmail. See Targets and Building datafiles.
Evaluate with the SDK#
Load the datafile into an SDK and ask it for values.
Install the SDK#
The JavaScript SDK is universal. The same package runs in Node.js and in browsers, and SDKs for other languages read the same datafile.
npm install @featurevisor/sdkFor this trial, install it in the project directory. Your applications install it in their own repositories.
Applications normally fetch the datafile from a remote location, such as your CDN, so new configuration reaches them without a release. To keep this trial on your machine, the script below reads it from disk instead. In your application shows the fetch.
Run it locally#
Create a script that reads the datafile you just built:
import { readFileSync } from 'node:fs'import { createFeaturevisor } from '@featurevisor/sdk'// Read from disk for this script.// Applications usually fetch it from a CDN.const datafile = JSON.parse( readFileSync('datafiles/featurevisor-all.json', 'utf8'),)const f = createFeaturevisor({ datafile, logLevel: 'warn' })const dutch = { userId: 'user-4', country: 'nl',}const german = { userId: 'user-9', country: 'de',}console.log(f.isEnabled('checkout', dutch))console.log(f.isEnabled('checkout', german))console.log(f.getVariable('supportEmail', dutch))console.log(f.getVariable('supportEmail', german))node try-checkout.mjstruefalseEvaluations are synchronous and use the datafile in memory. logLevel: 'warn' hides the SDK's startup messages.
In your application#
An application fetches the datafile from wherever you publish it, usually a CDN:
import { createFeaturevisor } from '@featurevisor/sdk'const response = await fetch('https://cdn.yoursite.com/featurevisor-all.json')if (!response.ok) throw new Error(`HTTP ${response.status}`)const f = createFeaturevisor({ datafile: await response.json() })// Set context once, for example after signing in.f.setContext({ userId: 'user-4', country: 'nl',})f.isEnabled('checkout') // trueContext passed to a single call is merged over the instance context for that call only. Your application decides when to fetch a newer datafile. See Deployment.
Ship it#
Featurevisor changes go through Git like any other code:
- Commit the project and open a pull request for each change.
- Run
npx featurevisor lintandnpx featurevisor testin CI, so a failing spec blocks the merge. - On merge, build the datafiles and upload them to your CDN or storage.
GitHub Actions has ready workflows, and Deployment covers other setups.
To browse what you built, run the Catalog. It opens at http://127.0.0.1:3000/ and reloads as you edit:
npx featurevisor catalogNext steps#
- Check your definitions before they ship with test specs, and run them with
npx featurevisor test. - Evaluate any context from your terminal with
npx featurevisor evaluate, and add--explainto see why. - Split users between versions with variations, like the
pricingexperiment in How it works. - Use objects, arrays and nested overrides in variables, or bind values to a feature's variations with feature variables.
- Give each application its own datafile with targets.
- Choose the SDK for your language.
- Follow a complete workflow, such as a gradual rollout or an A/B test.
- Diagnose unexpected results with Troubleshooting.

