Reference

API Reference: Core

Use the pure TypeScript engine for local flag evaluation, targeting, segments, and deterministic rollouts

Package overview

@flagforge/core is the dependency-free, pure TypeScript evaluation engine shared by the FlagForge API and @flagforge/sdk. It performs no I/O: pass an environment-specific EvaluatableFlag, an EvaluationContext, and optional segments to receive an EvaluationResult.

Install it in the application or runtime that will perform evaluation:

bash
pnpm add @flagforge/core

Import the engine and its public types from the package root:

typescript
import {
  evaluateAll,
  evaluateFlag,
  type EvaluatableFlag,
  type EvaluationContext,
} from "@flagforge/core";

The SDK uses the same engine after bootstrapping flag definitions. Use the core package directly when your runtime already has the definitions and needs evaluation without a per-check network call.

Note:

The engine does not fetch configuration or persist changes. Obtain the per-environment flag definitions from your configuration workflow, then pass them to the evaluation functions.

Evaluation functions

Evaluate one flag

The evaluateFlag function evaluates one flag against one context.

typescript
function evaluateFlag(
  flag: EvaluatableFlag,
  context: EvaluationContext,
  segments?: Segment[],
): EvaluationResult;
ParameterTypeDescription
flagEvaluatableFlagThe flag definition to resolve.
contextEvaluationContextThe subject key and optional attributes used by conditions and rollouts.
segmentsSegment[] (optional)Known segment definitions used by inSegment conditions.

The result includes the flag key, selected variation key, resolved value, and evaluation reason:

typescript
const context: EvaluationContext = {
  key: "user-123",
  attributes: { plan: "pro", country: "GB" },
};

const result = evaluateFlag(flag, context);

console.log(result.variationKey); // For example: "on"
console.log(result.value);        // For example: true
console.log(result.reason);       // For example: "RULE_MATCH"

Evaluation follows this order:

  1. A disabled flag serves offVariationKey with reason OFF.

  2. An enabled flag checks rules in array order. The first rule whose conditions all match serves its fixed variation or rollout result with reason RULE_MATCH.

  3. If no rule matches, the flag serves defaultVariationKey with reason FALLTHROUGH.

Evaluate all flags

The evaluateAll function evaluates a collection of flags for one context and returns a result map keyed by flag key.

typescript
function evaluateAll(
  flags: EvaluatableFlag[],
  context: EvaluationContext,
  segments?: Segment[],
): Record<string, EvaluationResult>;
typescript
const results = evaluateAll([flag], context);
const checkout = results["new-checkout"];

if (checkout?.value === true) {
  renderNewCheckout();
}

evaluateAll accepts the same optional segment definitions as evaluateFlag, so a group of flags can resolve against one evaluation context and segment set.

Flag and evaluation types

The engine evaluates a flattened, per-environment flag definition. Variations are addressed by stable string keys, not numeric indexes.

Evaluatable flag definitions

typescript
type EvaluatableFlag = {
  key: string;
  type: FlagType;
  enabled: boolean;
  variations: Variation[];
  defaultVariationKey: string;
  offVariationKey: string;
  rules: TargetingRule[];
};

The type field supports boolean, string, number, and JSON flag values. defaultVariationKey is used after rule evaluation falls through; offVariationKey is used when enabled is false.

Named variations

typescript
type Variation = {
  key: string;
  value: FlagValue;
  name?: string;
};

key is the stable identifier referenced by defaults, rules, and rollout branches. name is an optional human-friendly label.

Evaluation contexts

typescript
type EvaluationContext = {
  key: string;
  attributes?: Record<string, AttributeValue>;
};

key must be a stable subject identifier. Percentage rollouts use it as their default bucketing value. attributes supplies values for targeting conditions and segment membership.

Evaluation results

typescript
type EvaluationResult = {
  flagKey: string;
  variationKey: string;
  value: FlagValue;
  reason: EvaluationReason;
};

reason identifies why the result was selected. The documented evaluation reasons include OFF, RULE_MATCH, and FALLTHROUGH.

Targeting and segments

Targeting rules and conditions

A TargetingRule is evaluated in order. Its conditions are combined with logical AND; a matching rule can select one fixed variation or one rollout.

typescript
type TargetingRule = {
  id: string;
  conditions: Condition[];
  variationKey?: string;
  rollout?: Rollout;
};

type Condition = {
  attribute: string;
  operator: Operator;
  values: AttributeValue[];
  negate?: boolean;
};

Operator supports the following condition names:

OperatorTypical use
equalsMatch an attribute value.
inMatch one of several values.
containsMatch contained text or values.
startsWithMatch a string prefix.
endsWithMatch a string suffix.
greaterThanCompare ordered values.
greaterThanOrEqualCompare ordered values, including equality.
lessThanCompare ordered values.
lessThanOrEqualCompare ordered values, including equality.
semverGreaterThanCompare semantic versions.
semverLessThanCompare semantic versions.
matchesRegexMatch a regular-expression condition.
inSegmentMatch membership in named segments.

For inSegment, values contains segment keys and attribute is ignored. Set negate to invert the condition result.

Segments and segment resolution

A segment is a reusable audience definition whose conditions must all match:

typescript
type Segment = {
  key: string;
  conditions: Condition[];
};

type SegmentResolver = (key: string) => Segment | undefined;

Use matchCondition when implementing or inspecting one condition, including an inSegment condition that needs a resolver for known segments.

typescript
function matchCondition(
  condition: Condition,
  context: EvaluationContext,
  resolveSegment: SegmentResolver,
): boolean;

For normal flag evaluation, pass segments to evaluateFlag or evaluateAll; the engine uses them when resolving segment conditions.

Rollouts and bucketing

Rollout definitions

A rollout distributes a matching rule across weighted variation branches. Each branch weight is measured out of BUCKET_RESOLUTION.

typescript
type Rollout = {
  branches: RolloutBranch[];
  bucketBy?: string;
};

type RolloutBranch = {
  variationKey: string;
  weight: number;
};

The default resolution constant and bucketing function are:

typescript
const BUCKET_RESOLUTION = 100000;

function bucketOf(flagKey: string, bucketValue: string): number;

By default, the bucket is derived from the context key. Set bucketBy to use a context attribute instead. Because bucketing uses the flag key and bucket value, a subject remains in the same bucket for a given flag and bucket value.

typescript
const rollout: Rollout = {
  branches: [
    { variationKey: "on", weight: 25_000 },
    { variationKey: "off", weight: 75_000 },
  ],
  bucketBy: "accountId",
};

const bucket = bucketOf("new-checkout", "account-42");
console.log(bucket); // An integer in the rollout resolution range

Keep rollout branch variation keys aligned with the flag's variations. A rule either supplies variationKey or rollout; these are mutually exclusive choices.

Supporting value types

The module also exports the shared aliases used by the definitions above:

ExportPurpose
FlagTypeThe flag's supported type: boolean, string, number, or JSON.
FlagValueA concrete value served by a variation.
JsonValueA JSON-serializable value for JSON flags and comparisons.
AttributeValueA primitive value carried by an evaluation context attribute.
EvaluationReasonThe reason attached to an evaluation result.

Related APIs

SDK client

Bootstrap definitions from FlagForge and evaluate them locally with typed client helpers.

Core evaluation guide

See the core-engine integration workflow and when to reuse it outside the hosted API.

How evaluation works

Review evaluation order, context fields, targeting, segments, and rollout semantics.