Featurevisor

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

Create a project

Run these commands in an empty directory:

Commands
npx @featurevisor/cli@latest init
npm install

If 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:

Project
  • featurevisor.config.js project configuration
  • attributes/ values your application passes in
    • country.yml
    • deviceId.yml
    • userId.yml
  • segments/ named audiences built on attributes
    • netherlands.yml
  • features/ flags, variations and variables
    • checkout.yml we will add it later
    • showCookieBanner.yml
  • variables/ typed configuration
    • supportEmail.yml we will add it later
  • targets/ what each datafile contains
    • all.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.

Command
npx skills add featurevisor/featurevisor

Then ask your agent to write the feature and the variable in this guide for you:

Prompt

/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:

attributes/country.yml
description: Country
type: string

userId 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:

segments/netherlands.yml
description: The Netherlands
conditions:
- attribute: country
operator: equals
value: nl

Features 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:

features/checkout.yml
description: Checkout redesign
bucketBy: userId
rules:
- key: netherlands
conditions: netherlands
percentage: 100
- key: everyone
conditions: '*'
percentage: 25

Rules 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:

variables/supportEmail.yml
description: Support email shown in checkout
type: string
defaultValue: [email protected]
overrides:
- key: netherlands
conditions: netherlands
value: support-[email protected]

Everyone 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:

Command
npx featurevisor build
Output
Target: all
✔ datafiles/featurevisor-all.json
Datafiles built

The 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.

Command
npm install @featurevisor/sdk

For 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:

try-checkout.mjs
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))
Command
node try-checkout.mjs

Evaluations 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:

your-app/index.js
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') // true
f.getVariable('supportEmail') // '[email protected]'

Context 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:

  1. Commit the project and open a pull request for each change.
  2. Run npx featurevisor lint and npx featurevisor test in CI, so a failing spec blocks the merge.
  3. 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:

Command
npx featurevisor catalog

Next steps

Previous
How it works