feature-flags
Tiny, framework-agnostic feature flags for TypeScript.
@sparkstone/feature-flags is a small, framework-agnostic TypeScript library for defining and evaluating feature flags. It supports simple boolean “allow” flags as well as integer-based constraints (exact, minimum, and maximum), making it useful for feature rollouts, limits, and environment-based behavior.
Links:
- GitHub: https://github.com/Sparkstonepdx/feature-flags
- npm: https://www.npmjs.com/package/@sparkstone/feature-flags
What it does
-
Boolean feature flags
Simple on/off flags usingtype: "allow". -
Integer constraints & ranges
Exact values, minimums, and maximums for limits like quotas, thresholds, or build numbers. -
Tier-based segmentation
Every flag includes a free-formtierstring for environments, cohorts, regions, or plans. -
Framework-agnostic
Works anywhere TypeScript or JavaScript runs—no React, no hooks, no globals required. -
Multi-format builds
Ships ESM, CJS, and UMD bundles with type definitions.
Installation
npm i @sparkstone/feature-flags
or
pnpm add @sparkstone/feature-flags
or
yarn add @sparkstone/feature-flags
Quick start
import { featureFlags, FeatureFlag } from "@sparkstone/feature-flags";
const flags: FeatureFlag[] = [
{ name: "newDashboard", tier: "beta", type: "allow", value: true },
{ name: "maxUploads", tier: "", type: "int:max", value: 10 },
{ name: "minAge", tier: "eu", type: "int:min", value: 16 },
{ name: "build", tier: "qa", type: "int", value: 1234 },
];
featureFlags.load(flags);
if (featureFlags.isAllowed("newDashboard", "beta")) {
// show experimental UI
}
if (featureFlags.isInRange("maxUploads", "", 7)) {
// within allowed cap
}
How tiers work
Each flag is uniquely identified by name + tier. Internally the key is:
{name}.{tier}
This makes tiers a flexible way to segment behavior:
- environments:
dev,qa,prod - cohorts:
beta,control - regions:
eu,us - plans:
free,pro
Keeping names stable and varying tiers makes it easy to reason about rollout logic.
Browser & Node support
- Browser / UMD: drop-in via
dist/main.umd.js - ESM: modern bundlers and Node
- CJS: legacy Node environments
- Types: included
.d.tsfiles
Microbundle is used to produce all outputs cleanly.
Why it exists
Feature flags are often over-engineered or tightly coupled to frameworks. feature-flags focuses on the core mechanics—clear semantics, predictable evaluation, and zero runtime magic—so you can layer your own persistence, reactivity, or remote loading on top without fighting the library.
It’s designed to be small, explicit, and easy to delete if your needs change.
This remind you of a problem you've been dealing with?
I'd be happy to discuss it with you and see if it's something we could turn into a solution.
Book a call