Schema and rule engine for feature flags and config resolution
Inspired by OpenAPI and Swagger
Documentation | Quick Start | Concepts
- Define flags and config as definitions and declare which variation is served based on conditions.
- TypeScript-first with Zod validation.
- Supports
booleans,strings,numbers,arraysandobjectsas resolved variation values. - Supports both
yamlorjson. - Runtime evaluation against user defined context.
- Supports annotations for condition chaining and cross-dependency.
- Ability to define presets for condition reuse.
- Extensible with custom conditions.
- Store definitions in files and manage them in version control or serve them from an API.
A browser based schema configurator is also provided / available.
| Package | Description |
|---|---|
showwhat |
Main API for resolving feature flags and config values |
@showwhat/core |
Rule engine, schemas, parsers, and in-memory data source |
@showwhat/configurator |
React UI library for visual rule editing |
@showwhat/openfeature |
OpenFeature bridge for showwhat definitions |
| webapp | Browser app for authoring and testing definitions |
| docs | Documentation site |
npm install showwhat
pnpm add showwhat
yarn add showwhat
# Other runtimes
bun add showwhat
deno install npm:showwhatWrite a YAML (or JSON) file with a definitions root key. Each definition has one or more variations evaluated top-to-bottom — the first match wins.
# flags.yaml
definitions:
checkout_v2:
variations:
- value: true
conditions:
- type: env
value: prod
- value: false # default — no conditions means always matchesimport { showwhat, MemoryData } from "showwhat";
// Load definitions into an in-memory data source
const data = await MemoryData.fromYaml(fs.readFileSync("flags.yaml", "utf8"));
// Resolve flags against a runtime context
const results = await showwhat({
keys: ["checkout_v2"],
context: { env: "prod" },
options: { data },
});Every result entry is either { success: true, value } or { success: false, error }:
const entry = results["checkout_v2"];
if (entry.success) {
console.log(entry.value); // true
}Each definition lists variations in priority order. A variation matches when all its conditions pass. A variation with no conditions acts as a catch-all default.
definitions:
signup_flow:
variations:
- value: "v2"
conditions:
- type: string
key: tier
op: in
value: [enterprise, pro]
- value: "v1" # default
max_upload_size:
variations:
- value: 100
conditions:
- type: number
key: tier_level
op: gte
value: 2
- value: 25Values can be booleans, strings, numbers, arrays, or full objects.
| Type | Description | Example |
|---|---|---|
env |
Shorthand for matching context.env |
{ type: env, value: prod } |
string |
Compare any string key | { type: string, key: tier, op: eq, value: pro } |
number |
Compare any numeric key | { type: number, key: level, op: gte, value: 2 } |
bool |
Compare any boolean key | { type: bool, key: mobile, value: true } |
datetime |
Compare any datetime key | { type: datetime, key: at, op: gt, value: "2025-01-01T00:00:00Z" } |
startAt |
Passes when context.at >= value |
{ type: startAt, value: "2025-06-01T00:00:00Z" } |
endAt |
Passes when context.at < value |
{ type: endAt, value: "2025-07-01T00:00:00Z" } |
and |
All child conditions must pass | { type: and, conditions: [...] } |
or |
Any child condition must pass | { type: or, conditions: [...] } |
See the Conditions guide for operators, regex matching, and more.
Presets let you define reusable condition shorthands to keep definitions DRY:
definitions:
premium_feature:
variations:
- value: true
conditions:
- type: tier # uses the "tier" preset below
op: in
value: [pro, enterprise]
- value: false
presets:
tier:
type: string
key: tier # always reads context.tierSee the Presets guide for composite presets and overrides.
showwhat assumes definition authors are trusted. See the Security guide for considerations when accepting definitions from untrusted sources.
See CONTRIBUTING.md for development setup, commands, and guidelines.
This codebase was developed with the assistance of AI tools:
- Library packages (eg: core, showwhat): Human architected and coded, with AI pair programming and assistance.
- UI packages (eg: configurator): Human architected and refined. AI-implemented.
- Tests: AI-implemented.
All outputs are reviewed by humans.