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.
❯
STOP SHIPPING FLAGS YOU CAN'T TRUST.
Runtime flags are silent, untyped, and untraceable. VoidFlag makes them compile-time citizens.
- Typo compiles fine, fails at runtime
- Undefined flags return false silently
- No types for values or variants
- Changes in audit logs, not Git
- Unknown flags won't compile
- Schema-defined, build-time types
- Strict values and metadata
- Versioned state reviewed in PRs
FLAGS TREATED LIKE CODE
Typed at build time. Versioned in Git. Controlled without redeploys.
Flags live in a schema file inside your repo — not in a dashboard. They exist at build time and generate types automatically.
Undefined flags don't silently return false. They throw at compile time. Misuse is caught before it reaches production.
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.
EVERYTHING THE TYPE SYSTEM NEEDS
Six primitives that cover the whole lifecycle from definition to rollout
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.
flag darkMode {
type bool
fallback false
}
flag theme {
type string
fallback "light"
}
flag fontSize {
type number
fallback 16
}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.
# 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 stagingNo 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.
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; // trueNo 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.
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<...>; ... }'.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.
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();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.
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 disabledlive 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"Built for the TypeScript ecosystem.
Backend-first today. Expanding to more runtimes soon.
Node.js
Full runtime support
Express
Works inside route handlers
NestJS
Module integration
Next.js
Server-side & Edge
Bun
Deno
.NET
Go
Java
Python
join the waitlist
be first when voidflag ships
no spam · unsubscribe anytime