Featurevisor
You are helping the user author and query a Featurevisor project — a Git-based feature management tool. Featurevisor projects are standalone repositories of YAML (default) or JSON definitions that compile into per-environment/per-tag datafiles consumed by SDKs.
The full documentation as a single file is at https://featurevisor.com/llms.txt. Fetch it on demand if a topic isn't covered in this skill's references.
Orient yourself first
Before authoring anything, take a few seconds to ground in the actual project. Always run these once at the start of a Featurevisor task:
npx featurevisor config --json --pretty
npx featurevisor info
From the config note:
environments— array of env names (orfalsefor no envs). Their names driverules:,force:,expose:keys.tags— must include any tag you put on a feature.splitByEnvironment— iftrue, rules/force/expose live inenvironments/<env>/<feature>.yml, not in the base feature file.parser— if"json"author in JSON; otherwise YAML. Inspect a couple of existing files to confirm the on-disk style.defaultBucketBy— default isuserId, but projects may override.- Directory paths (
featuresDirectoryPath, etc.) — respect any overrides.
Then read one or two existing entities (a feature, a segment) to match local style — indentation, quoting, comment density, key ordering — before adding new ones.
When to load which reference
This file is loaded eagerly. The files below are loaded only when relevant — read them in full before authoring or debugging in that area, don't rely on the summary in this file.
| Task | Read |
|---|---|
| Create or edit a feature (flags, variations, variables, etc.) | features.md |
| Write or change segment conditions | segments.md |
| Look up a condition operator | operators.md |
| Define or change an attribute | attributes.md |
Variables, JSON-Schema-ish types, reusable schemas/ |
variables-schemas.md |
Variable overrides with deep merge (mutations) |
variables-schemas.md |
Mutually-exclusive experiments via groups/ |
groups.md |
Bucketing, bucketBy, state files, sticky |
bucketing.md |
| Tags — per-app datafile bundling | tags.md |
| Scopes — pre-evaluated, smaller datafiles | scopes.md |
| Namespaces — directory-based feature/segment key prefixes | namespaces.md |
featurevisor.config.js, environments, splitByEnvironment |
configuration.md |
| JSON / TOML / other format projects | custom-parsers.md |
| Build datafiles, deploy to CDN, CI pipeline | building-datafiles.md |
Write a .spec.yml test, run featurevisor test |
testing.md |
Any CLI invocation, flags, list/find-usage/evaluate |
cli.md |
| Answer "what's enabled where / who uses X" | querying.md |
| Code generation (typed TS bindings) | code-generation.md |
| Analytics activation hooks (GA4 / Segment / etc.) | tracking.md |
| Common patterns — A/B, multivariate, entitlements, dependencies, testing-in-prod, deprecation, microfrontends, ownership, trunk-based dev | recipes.md |
| Terminology refresher | glossary.md |
Per-entity templates live in templates/ — copy and adapt rather than writing from memory.
A complete end-to-end mini project lives in templates/example-project/. Use it as the source of truth for "show me how a realistic Featurevisor project hangs together" requests.
Core authoring rules
These apply to every change. Internalize them; the references add depth, they do not override these.
1. Bucketing and rule keys are append-only contracts
bucketByis what keeps a user's experience consistent as percentages ramp. Pick once, never silently change it.- Default for signed-in users:
userId. For anonymous users:deviceId(or whatever the project calls it). The attribute names may differ in this project — read theattributes/directory and ask the user which to use if it isn't obvious. Do not invent attribute names. - Combine attributes with a list (
bucketBy: [orgId, userId]) or fall back viabucketBy: {or: [userId, deviceId]}. - Each rule's
keymust be unique within its environment and must not change once users are bucketed against it. Renaming a rule key re-buckets users — the same user can lose or gain the feature. Add a new rule rather than renaming. - Increasing
percentageover time is safe only if the rule key stays stable.
2. First matching rule wins
Rules are evaluated top-to-bottom per environment. Put narrow targeting (e.g. country-specific rollouts at 100%) before the catch-all segments: '*' rule.
3. Don't author rules that target unknown segments or attributes
Before referencing segments: foo in a rule, confirm segments/foo.yml exists (or create it). Same for attributes referenced inside segment conditions. Run npx featurevisor lint after edits — it catches dangling refs, percentage-sum errors in groups and variations, and schema mismatches.
4. Respect splitByEnvironment if enabled
If splitByEnvironment: true:
- Base file
features/<key>.ymlholds metadata (description, tags, bucketBy, variations, variablesSchema, required, etc.) — norules,force, orexpose. - Per-environment file
environments/<env>/<key>.ymlholdsrules,force,exposefor that env.
5. Variations weights sum to 100; group slot percentages sum to 100
And a feature in a group cannot use a rollout percentage higher than its slot's percentage.
6. After any edit, lint
npx featurevisor lint
If you wrote or changed a test spec, also run:
npx featurevisor test --keyPattern=<theKey>
CLI: run freely
All featurevisor CLI commands are local and safe to run without confirmation. For build, always pass --no-state-files so it doesn't increment the project's revision locally:
npx featurevisor build --no-state-files
The most useful commands for an authoring agent (full reference in cli.md):
| Command | Purpose |
|---|---|
npx featurevisor config --json --pretty |
Project configuration |
npx featurevisor info |
Counts of features / segments / attributes / tests |
npx featurevisor lint |
Validate definitions (run after every edit) |
npx featurevisor list --features --json [--filters…] |
Find features by tag, env, variable, archived, etc. |
npx featurevisor list --segments --json |
List segments |
npx featurevisor list --attributes --json |
List attributes |
npx featurevisor find-usage --segment=<key> |
Where a segment is used |
npx featurevisor find-usage --attribute=<key> |
Where an attribute is used |
npx featurevisor find-usage --feature=<key> |
Feature usage details |
npx featurevisor find-usage --unusedSegments |
Dead segments |
npx featurevisor find-usage --unusedAttributes |
Dead attributes |
npx featurevisor find-duplicate-segments |
Segments with identical conditions |
npx featurevisor evaluate --environment=<e> --feature=<k> --context='{…}' |
Why a feature evaluates the way it does (debug) |
npx featurevisor assess-distribution --environment=<e> --feature=<k> --context='{…}' --populateUuid=userId --n=1000 |
Simulate rollout distribution |
npx featurevisor test [--keyPattern=…] [--assertionPattern=…] |
Run test specs |
npx featurevisor build --no-state-files |
Build datafiles without touching local revision/state |
Prefer the CLI over grepping when answering questions like "what features use segment X?", "which features are enabled in production?", or "why does feature F evaluate to disabled for this context?". The CLI's --json output is parseable and authoritative.
Common authoring flows
Adding a new feature flag
- Read the existing
features/directory to match conventions (file naming, comment style). - Confirm the attribute used for
bucketByexists inattributes/; ask the user which to use if multiple plausible options exist (e.g.userIdvsdeviceId). - Create
features/<key>.ymlfrom templates/feature.yml. - If targeting specific segments, ensure each referenced segment exists in
segments/— create it from templates/segment.yml if not. - Run
npx featurevisor lint. - Offer (don't force): "I can add a
tests/features/<key>.spec.ymlcovering this — want me to?" If yes, use templates/test-feature.spec.yml.
Adding variations (A/B test)
Read features.md on variations, then use templates/feature-with-variations.yml. Remind the user that weights sum to 100 and the control/treatment names are conventional only.
Adding variables (remote config)
Read variables-schemas.md — covers all variable types, the inline JSON-Schema-ish form, reusable schemas/, variation-level variables, rule-level variables: and variableOverrides:, and the mutations feature for deep-merge overrides. Use templates/feature-with-variables.yml as the starting shape.
Complex targeting (and/or/not)
Both segment conditions and feature rule segments support and, or, not with nesting. See segments.md and templates/segment-complex.yml.
Mutual-exclusion experiments
Read groups.md. Plan slot percentages before adding rules — once users are bucketed in a group, changing slot percentages re-buckets them. Use templates/group.yml.
Force-enabling for QA / a specific user
Use force: on the feature (per-environment), not rules. No key/percentage needed. See features.md.
Debugging an evaluation
Use npx featurevisor evaluate --environment=<e> --feature=<k> --context='{…}' --verbose rather than reading the YAML and reasoning by hand. The evaluation flow (sticky → required → forced → rules → bucketing) is documented in features.md.
Querying ("what's enabled where?", "who uses this segment?")
See querying.md. It shows the right list/find-usage/evaluate invocations for the common questions a developer asks about an existing project.
Recipes for higher-level use cases
When the request matches a named pattern — A/B test, multivariate, mutual exclusion, dependencies, remote config, entitlements, testing in production, deprecation, trunk-based development, microfrontends, decoupling release from deploy, ownership — open recipes.md and adapt the matching section. It links back to the granular references for shape details.
SDK use cases
SDK implementation is out of scope for this skill — focus on authoring and querying. If the user needs SDK help, point them at:
- JavaScript / TypeScript: https://featurevisor.com/docs/sdks/javascript
- React: https://featurevisor.com/docs/react
- Vue: https://featurevisor.com/docs/vue
- React Native: https://featurevisor.com/docs/react-native
- Other languages (Python, Ruby, Go, Java, Swift, PHP, etc.): https://featurevisor.com/docs/sdks
- Full docs as a single file: https://featurevisor.com/llms.txt
You may briefly explain how an authored feature would be consumed (f.isEnabled('key'), f.getVariation('key'), f.getVariable('key', 'varName')), but don't write application code unless asked.
What not to do
- Do not change a feature's
bucketByor a rule'skey"to clean things up" — that re-buckets users. - Do not invent attribute or segment names. Verify they exist; create them explicitly if needed.
- Do not rename or delete attributes/segments before checking
find-usage. - Do not add
expose:unless the user asks — it's a short-term migration tool. - Do not run
buildwithout--no-state-files. - Do not skip
npx featurevisor lintafter edits.
Source: featurevisor/featurevisor — distributed by TomeVault.