flaggy v0.1 · open source · self-hostable

Feature flags that don't suck. Fast, OpenFeature-compatible, self-hostable. Drop in the SDK of your choice and ship.

← user · role · % · A/B · all on the hot path →
drop in

From git clone to live flag in three steps.

  1. 01step 1

    Self-host

    One Postgres + one binary. Migrations on first boot.

  2. 02step 2

    Drop in the SDK

    OpenFeature provider for Node or Go. Local eval after init.

  3. 03step 3

    Ship

    Targeting + rollouts + A/B from the dashboard. ~0ms p99.

live demo

Watch a flag resolve.

A real cascade of rules against the context you paste in. First match wins, deterministic FNV-1a bucketing on the rest.

context
attrs.role
rules
#0usertargetingKey ∈ ["alice", "carol"]on
#1rolerole ∈ ["internal"]on
#2percentage25% of role=beta (FNV-1a bucketed)on
#3defaultdefault variantoff
result
flag
new-checkout
value
on
variant
on
reason
TARGETING_MATCH · r1

try `bob` · role=`free` · or hit ⌘K

what it does

The targeting you want, on the hot path.

User targeting

Allowlist specific users by id. First-match wins.

Role targeting

Match on role attributes carried in the eval context.

Percentage rollouts

Deterministic FNV-1a bucketing. Stable across toggles.

Weighted A/B

Split traffic across variants by weight. Same hash family.

OpenFeature-native

Drop-in provider, not a custom SDK. Server-side, ~0ms p99.

Self-hostable

One binary, one Postgres. No external deps in OSS mode.

SDKs

One eval engine, three implementations.

Same golden vectors run against the Go API, the Node SDK, and (soon) the browser SDK. Drift between any two fails the test.

TypeScript

shipped
pnpm add @flaggy/openfeature-provider
OpenFeature.setProviderAndWait(
  new FlaggyProvider({ baseUrl, token })
);
const client = OpenFeature.getClient();
await client.getBooleanValue("new-checkout", false, ctx);

Go

shipped
go get github.com/flaggy/flaggy/sdks/openfeature-provider-go
provider := flaggy.NewProvider(flaggy.ClientOptions{
    BaseURL: baseURL, Token: token,
})
provider.Init(ctx)
openfeature.SetProvider(provider)
client := openfeature.NewClient("my-app")
v, _ := client.BooleanValue(ctx, "new-checkout", false, ec)

Browser

soon
// @flaggy/openfeature-web-provider
// client-side bundle, signed snapshot, ETag fallback

Python

soon
# pip install flaggy-openfeature
# PEP-8-friendly Provider, same eval contract