Featurevisor

Advanced

Command Line Interface (CLI) Usage

Beyond just initializing a project and building datafiles, Featurevisor CLI can be used for a few more purposes.

Installation

Use npx to initialize a project first:

$ mkdir my-featurevisor-project && cd my-featurevisor-project
$ npx @featurevisor/cli init

If you wish to initialize a specific example as available in the monorepo:

$ npx @featurevisor/cli init --example=json

After you have installed the dependencies in the project:

$ npm install

You can access the Featurevisor CLI from inside the project via:

$ npx featurevisor

Learn more in Quick start.

Linting

Check if the definition files have any syntax or structural errors:

$ npx featurevisor lint

Use --json for machine-readable output, and --json --pretty for prettified JSON output.

Lear more in Linting.

Building datafiles

Generate JSON files, one per target and optional environment combination:

$ npx featurevisor build

Pass --target=<target> one or more times to build only those targets. Without it, all targets are built.

In a project with sets, you can build a single set by passing --set:

$ npx featurevisor build --set=storefront

Learn more in Building datafiles.

Testing

Test your features and segments:

$ npx featurevisor test

Pass --target=<target> one or more times to build only those target datafiles and run untargeted assertions plus assertions for the selected targets. Segment tests are not filtered.

In a project with sets, you can test a single set by passing --set:

$ npx featurevisor test --set=storefront

Learn more in Testing.

Promote between sets

In a project with sets, you can preview and apply promotions from one set to another.

Preview what would be copied:

$ npx featurevisor promote --from=dev --to=staging

Apply the promotion to write destination files:

$ npx featurevisor promote --from=dev --to=staging --apply

Learn more in Promotions.

Generate static catalog

Build the catalog:

$ npx featurevisor catalog export

Serve the built catalog (defaults to port 3000):

$ npx featurevisor catalog serve

Serve it in a specific port:

$ npx featurevisor catalog serve -p 3000

Learn more in Catalog.

Generate code

Generate TypeScript code from feature definitions:

$ npx featurevisor generate-code --language typescript --out-dir ./src

See output in ./src directory. Pass repeatable --tag=<tag> or --target=<target> options to generate the union of features needed by several tags or targets.

Learn more in code generation page.

Find duplicate segments

It is possible to end up with multiple segments having same conditions in larger projects. This is not a problem per se, but we should be aware of it.

We can find these duplicates early on by running:

$ npx featurevisor find-duplicate-segments

If we want to know the names of authors who worked on the duplicate segments, we can pass --authors:

$ npx featurevisor find-duplicate-segments --authors

Find usage

Learn where/if certain segments and attributes are used in.

For each of the find-usage commands below, you can optionally pass --authors to find who worked on the affected entities.

Segment usage

$ npx featurevisor find-usage --segment=my_segment

Attribute usage

$ npx featurevisor find-usage --attribute=my_attribute

Unused segments

$ npx featurevisor find-usage --unusedSegments

Unused attributes

$ npx featurevisor find-usage --unusedAttributes

Feature usage

$ npx featurevisor find-usage --feature=my_feature

Benchmarking

You can measure how fast or slow your SDK evaluations are for particular features.

The --n option is used to specify the number of iterations to run the benchmark for.

Pass --target=<target> one or more times to benchmark the same evaluation independently against each selected target datafile. Without it, the complete in-memory datafile is used.

The output includes both the total loop duration and individual evaluation timings:

  • Total duration: how long all benchmark iterations took together
  • Minimum duration: fastest individual evaluation
  • Average duration: average individual evaluation
  • Maximum duration: slowest individual evaluation

Use the individual evaluation timings when comparing SDK performance. The maximum value can include runtime pauses like garbage collection or process scheduling.

Feature

To benchmark evaluating a feature itself if it is enabled or disabled via SDK's .isEnabled() method against provided context:

$ npx featurevisor benchmark \
--environment=production \
--feature=my_feature \
--context='{"userId": "123"}' \
--n=1000

Variation

To benchmark evaluating a feature's variation via SDKs's .getVariation() method:

$ npx featurevisor benchmark \
--environment=production \
--feature=my_feature \
--variation \
--context='{"userId": "123"}' \
--n=1000

Variable

To benchmark evaluating a feature's variable via SDKs's .getVariable() method:

$ npx featurevisor benchmark \
--environment=production \
--feature=my_feature \
--variable=my_variable_key \
--context='{"userId": "123"}' \
--n=1000

Configuration

To view the project configuration:

$ npx featurevisor config

Printing configuration as JSON:

$ npx featurevisor config --json --pretty

Evaluate

To learn why certain values (like feature and its variation or variables) are evaluated as they are against provided context:

$ npx featurevisor evaluate \
--environment=production \
--feature=my_feature \
--context='{"userId": "123", "country": "nl"}'

This will show you full evaluation details helping you debug better in case of any confusion.

Pass --target=<target> one or more times to evaluate independently against the exact datafiles for those targets. With repeated targets and --json, the result is an array containing each target and its evaluations. A single target keeps the regular evaluation object shape.

It is similar to diagnostics in SDKs with debug level. But here instead, we are doing it at CLI directly in our Featurevisor project without having to involve our application(s).

If you wish to print the evaluation details in plain JSON, you can pass --json at the end:

$ npx featurevisor evaluate \
--environment=production \
--feature=my_feature \
--context='{"userId": "123", "country": "nl"}' \
--json \
--pretty

The --pretty flag is optional.

To print further logs in a more verbose way, you can pass --verbose:

$ npx featurevisor evaluate \
--environment=production \
--feature=my_feature \
--context='{"userId": "123", "country": "nl"}' \
--verbose

List

List datafiles

To list generated datafiles in the configured datafiles/ directory:

$ npx featurevisor list --datafiles

The result is a three-column table of paths relative to datafiles/, their uncompressed sizes, and their gzip-compressed sizes, excluding the REVISION file and hidden files. Size values are right-aligned and always show two decimal places; one-character B suffixes are padded to align with kB and mB. There is an empty line between directories. Directories beginning with dev appear first and those beginning with prod appear last. Sizes use colored B, kB, and mB suffixes in terminal output. With --json, each item has path, byte size, and byte gzipSize fields in the same order.

OptionDescription
--jsonprint as JSON
--prettypretty JSON

List features

To list all features in the project:

$ npx featurevisor list --features

Advanced search options:

OptionDescription
--archived=<true or false>by archived status
--description=<pattern>by description pattern
--disabledIn=<environment>disabled in an environment
--enabledIn=<environment>enabled in an environment
--jsonprint as JSON
--keyPattern=<pattern>by key pattern
--tag=<tag>by tag
--target=<target>selected by one or more repeatable targets
--variable=<variableKey>containing specific variable key
--variation=<variationValue>containing specific variation key
--with-testswith test specs
--with-variableswith variables
--with-variationswith variations
--without-testswithout any test specs
--without-variableswithout any variables
--without-variationswithout any variations

List segments

To list all segments in the project:

$ npx featurevisor list --segments

Advanced search options:

OptionDescription
--archived=<true or false>by archived status
--description=<pattern>by description pattern
--jsonprint as JSON
--keyPattern=<pattern>by key pattern
--prettypretty JSON
--with-testswith test specs
--without-testswithout any test specs

List attributes

To list all attributes in the project:

$ npx featurevisor list --attributes

Advanced search options:

OptionDescription
--archived=<true or false>by archived status
--description=<pattern>by description pattern
--jsonprint as JSON
--keyPattern=<pattern>by key pattern
--prettypretty JSON

List tests

To list all tests specs in the project:

$ npx featurevisor list --tests

Advanced search options:

OptionDescription
--applyMatrixapply matrix for assertions
--assertionPattern=<pattern>by assertion's description pattern
--jsonprint as JSON
--keyPattern=<pattern>by key pattern of feature or segment being tested
--prettypretty JSON

Assess distribution

To check if the gradual rollout of a feature and the weight distribution of its variations (if any exists) are going to work as expected in a real world application with real traffic against provided context, we can imitate that by running:

$ npx featurevisor assess-distribution \
--environment=production \
--feature=my_feature \
--context='{"country": "nl"}' \
--populateUuid=userId \
--n=1000

The --n option controls the number of iterations to run, and the --populateUuid option is used to simulate different users in each iteration in this particular case.

Further details about all the options:

  • --environment: the environment name
  • --feature: the feature key
  • --context: the common context object in stringified form
  • --populateUuid: attribute key that should be populated with a new UUID, and merged with provided context.
    • You can pass multiple attributes in your command: --populateUuid=userId --populateUuid=deviceId
  • --n: the number of iterations to run the assessment for
    • The higher the number, the more accurate the distribution will be
  • --target: assess the exact target datafile; repeat it to assess several targets independently
  • --verbose: print the merged context for better debugging

Everything is happening locally in memory without modifying any content anywhere. This command exists only to add to our confidence if questions arise about how effective traffic distribution in Featurevisor is.

Info

Shows count of various entities in the project:

$ npx featurevisor info

Pass --target=<target> one or more times to show counts and datafile sizes for each selected target in each environment. Without it, info shows the project-wide entity counts.

Version

Get the current version number of Featurevisor CLI, and its relevant packages:

$ npx featurevisor --version

Or do:

$ npx featurevisor -v
Previous
Fastify
Next
Tags