Getting started
This guide adds Feature Flags to a backend app, declares a few common flag types, evaluates a flag from a route, and uses request context for targeting.
Define Flags
Section titled “Define Flags”Import featureFlags and flag, create a product instance, and register it
with your app.
import { backend } from "@layeron/core"import { featureFlags, flag } from "@layeron/modules"
const app = backend({ project: "shop" })
const flags = featureFlags({ name: "main", namespace: "product", flags: { checkoutV2: flag.boolean({ default: false, environments: { preview: true, staging: true, prod: false, }, }),
pricingPageVariant: flag.variant({ default: "control", variants: ["control", "short-copy", "new-layout"], }),
maxUploadMb: flag.number({ default: 25, environments: { prod: 50, }, }), },})
app.use(flags)The Feature Flags instance identity is product/main. See
Namespaces for platform namespace defaults and naming rules.
Evaluate a Boolean Flag
Section titled “Evaluate a Boolean Flag”Use flags.enabled(...) when the result should be a boolean:
app.get("/checkout", async (request) => { const enabled = await flags.enabled("checkoutV2", { environment: "prod", })
return Response.json({ checkoutVersion: enabled ? "v2" : "v1", })})Read a Value Flag
Section titled “Read a Value Flag”Use flags.value<T>(...) for strings, numbers, variants, and JSON values:
app.get("/upload-limit", async (request) => { const maxUploadMb = await flags.value<number>("maxUploadMb", { environment: "prod", default: 25, })
return Response.json({ maxUploadMb })})Target a Tenant
Section titled “Target a Tenant”Add a tenant rule when a customer should receive a value before the rest of the audience:
const flags = featureFlags({ name: "main", flags: { checkoutV2: flag.boolean({ default: false, rules: [ flag.tenants(["tenant_acme"]).value(true), ], }), },})Pass the active tenant ID during evaluation:
const enabled = await flags.enabled("checkoutV2", { tenantId: tenant.id,})Target by Attributes
Section titled “Target by Attributes”Attributes let you use information from your own app model:
const flags = featureFlags({ name: "main", flags: { advancedReports: flag.boolean({ default: false, rules: [ flag.attribute("plan").equals("enterprise").value(true), ], }), },})const enabled = await flags.enabled("advancedReports", { tenantId: tenant.id, attributes: { plan: tenant.plan, },})Roll Out by Percentage
Section titled “Roll Out by Percentage”Use percentage rules for gradual launches:
const flags = featureFlags({ name: "main", flags: { checkoutV2: flag.boolean({ default: false, rules: [ flag.percentage(10, { stickiness: "userId" }).value(true), ], }), },})With stickiness: "userId", the same user keeps the same decision as the
percentage changes.
const enabled = await flags.enabled("checkoutV2", { userId: user.id,})Inspect the Decision
Section titled “Inspect the Decision”Use evaluate(...) when you want the selected value and the reason:
const decision = await flags.evaluate<boolean>("checkoutV2", { environment: "prod", tenantId: tenant.id, userId: user.id,})
console.log(decision.reason, decision.ruleId, decision.value)The decision reason is one of:
environmenttenantuserattributepercentagedefaultfallback
Next Steps
Section titled “Next Steps”- Rules and rollouts: Target tenants, users, attributes, and percentages in a predictable order.
- Environments: Use environment overrides and promotion habits across preview, staging, and production.
- Policy: Protect reads, publishes, history, rollback, and admin workflows.
- Publishing: Publish snapshots, inspect decisions, roll back changes, and audit flag updates.
- Examples: Adapt release, rollout, and runtime-limit patterns.
- API reference: Review flag config, decision results, history, rollback, and module methods.