v1.0.0 · EARLY ACCESS IS OPEN

Feature flags
that can’t silently break production

VoidFlag catches misconfigured flags at compile time. No loose strings. No silent failures. No guessing in production.

bash

But.., Why VoidFlag?

STOP SHIPPING FLAGS YOU CAN'T TRUST.

Runtime flags are silent, untyped, and untraceable. VoidFlag makes them compile-time citizens.

Before
Fragile
if (flags.get("new-chekout", false)) {
checkout.render();
}
  • Typo compiles fine, fails at runtime
  • Undefined flags return false silently
  • No types for values or variants
  • Changes in audit logs, not Git
After
Type-Safe
if (flags.newCheckout.enabled) {
checkout.render()
}
  • Unknown flags won't compile
  • Schema-defined, build-time types
  • Strict values and metadata
  • Versioned state reviewed in PRs
Philosophy

FLAGS TREATED LIKE CODE

Typed at build time. Versioned in Git. Controlled without redeploys.

Schema-first

Flags live in a schema file inside your repo — not in a dashboard. They exist at build time and generate types automatically.

Compile-time safety

Undefined flags don't silently return false. They throw at compile time. Misuse is caught before it reaches production.

Git as source of truth

State changes are versioned, reviewed in PRs, and traceable. No more hunting through audit logs.

Think Prisma-style schema discipline applied to feature flags. VoidFlag is built for teams who want strictness, not chaos.

Features

EVERYTHING THE TYPE SYSTEM NEEDS

Six primitives that cover the whole lifecycle from definition to rollout

01Schema-first

No more flags that only exist in a dashboard.

Every other provider defines flags in a UI you can't commit, review, or diff. VoidFlag defines them in a .vf file, your types, fallbacks, and constraints live in version control, not in someone's browser tab.

VoidFlag
flag darkMode {
  type bool
  fallback false
}

flag theme {
  type string
  fallback "light"
}

flag fontSize {
  type number
  fallback 16
}
02CLI workflow

No more pairing with a teammate just to add a flag.

Existing tools turn flag creation into a dashboard ritual, new form, new copy-paste. With VoidFlag, the entire lifecycle runs through the CLI. Init, generate, push, apply. No UI required, no tickets to ops.

Shell
# scaffold schema
vf init

# generate a typed client from schema
vf generate /src --lang ts

# sync schema with the server
vf push

# apply state to an environment
vf apply --env staging
03Live flag accessors

No more passing computed attributes on every call.

Other SDKs require you to recompute and re-supply every user attribute on each evaluation, if you forget, you get stale targeting. VoidFlag accessors read directly from the live store. No arguments, no ceremony, no drift.

TypeScript
const { theme, darkMode, fontSize } = client.flags;

theme.value;    // enabled ? value : fallback → 'light'
theme.enabled;  // true

darkMode.value;   // boolean
fontSize.value;   // number

// Snapshot, point-in-time copy
const snap = client.snapshot('darkMode');
snap.value;    // false
snap.fallback; // false
snap.rollout;  // 0
snap.enabled;  // true
04Fully typed

No more string keys that silently return any.

Other tools evaluate flags by string key, delete the flag in the dashboard, and your code still compiles, still resolves, still ships. VoidFlag derives every accessor from your schema. Typos are compile errors. Deleted flags break the build.

TypeScript
const { darkMode, theme, fontSize } = client.flags;

darkMode.value;  // boolean
theme.value;     // string
fontSize.value;  // number

// Typos don't compile.
const { darkMood } = client.flags;
//      ~~~~~~~~~
// Property 'darkMood' does not exist
// on type '{ darkMode: Accessor<...>; ... }'.
05DI-ready

No more redeploys to swap a dependency.

Most teams use flags for simple on/off gates and stop there. VoidFlag is designed to go further, use flag state as a runtime decision point inside your DI container. Swap entire service implementations, migrate providers, or A/B test service layers without touching a deploy.

TypeScript
const { useStripe } = client.flags;

// swap payment provider at runtime
const paymentService = useStripe.value
  ? new StripeService()
  : new PayPalService();

container.register(PaymentService, paymentService);

// gradual migration, stable per user
const svc = useStripe.isRolledOutFor(user.id)
  ? new StripeService()
  : new PayPalService();
06Stable rollouts

No more mysterious MAU counts and overage warnings.

Usage-based pricing on other platforms means your bill grows every time a flag is evaluated, and your dashboard fills with anonymous users you never asked for. VoidFlag rollouts are deterministic hash bucketing, no tracking, no MAU metering, no surprises at the end of the month.

TypeScript
const { darkMode, newCheckout } = client.flags;

// 20% rollout, deterministic per user
darkMode.isRolledOutFor(user.id);
// user_42 → bucket 17 → true  ✓
// user_99 → bucket 83 → false

// allEnabled(), gate on multiple flags at once
client.allEnabled(darkMode, newCheckout);
// false if any flag is disabled

live demo

Select a flag · tune its props · watch users resolve to value or fallback

A/B test: which hero copy does this user see?

"control" | "challenger"
fallbackcontrol
enabled
Flag is live — rollout decides who gets value vs fallback
value
What users inside rollout receive
rollout
% of users that receive value · rest get fallback
50%
user_42b72fallback control
user_99b30value challenger
user_07b1value challenger
user_88b62fallback control
user_42fallback
✦ beta
Feature flags for TS.
Schema-first.
✓ Express checkout
user_99value
✦ beta
New
Ship flags faster.
✓ Express checkout
user_07value
New
Ship flags faster.
Legacy checkout
user_88fallback
✦ beta
Feature flags for TS.
Schema-first.
✓ Express checkout
Ecosystem

Built for the TypeScript ecosystem.

Backend-first today. Expanding to more runtimes soon.

SupportedREADY
  • Node.js

    Node.js

    Full runtime support

  • Express

    Express

    Works inside route handlers

  • NestJS

    NestJS

    Module integration

  • Next.js

    Next.js

    Server-side & Edge

Coming SoonIn Progress
  • BunBun
  • DenoDeno
  • .NET.NET
  • GoGo
  • JavaJava
  • PythonPython
EARLY ACCESS

join the waitlist

be first when voidflag ships

no spam · unsubscribe anytime