Same user, same bucket, everywhere
One engine runs at the edge, in the SDK, in the CLI and in CI. Type any user key: the result is computed in your browser with the same code.
hash("checkout-v2", "user_1") → 40.61 < 50 ✓ · rollout 50%
Feature flags · Release safety
NanoFlags adds drafts, independent approvals and scenario checks to every flag change, then delivers it as a signed bundle to your SDKs in about 0.2 seconds. Evaluation runs locally in your app, so a network blip never becomes an outage.
Explore plan $0Apache-2.0 SDKOpenFeature provider
Live proof: p50 222 ms · p95 325 mscommit → SDK, last 24 hEd25519-signed bundlesApache-2.0 SDKSee live latency
| Probe region | p50 (ms) | p95 (ms) |
|---|---|---|
| KIX Osaka | 189 | 279 |
| MEL Melbourne | 194 | 281 |
| LHR London | 229 | 317 |
| ATL Atlanta | 253 | 340 |
| DEN Denver | 255 | 341 |
Why NanoFlags
Four things built into every flag change. Each one is enforced by the product or measured in public, and each links to the page that shows how.
A scenario check is the value you expect a flag to return for a given context. Where checks are required, a single failure blocks the publish.
The author and anyone who edited the draft can't approve it. An approval is tied to the exact draft and goes stale if the draft changes.
Bound to this exact draft. Any edit makes it stale.
Ed25519 signatures, checked by the SDK by default. A tampered or unsigned config is rejected, and your app keeps its last good config.
Synthetic probes time each publish from database commit to SDK every 5 minutes. The results and the method are public.
222ms
p50 by probe region · last 24 h
p50 · commit → SDK · last 24 hp95 325 ms · 1,418 samples
Required approvals and scenario checks are part of Team and Scale. On those plans, every new Production environment starts with both turned on.
Live demo · real edge
This is a public NanoFlags environment. Press the switch: the change is published, signed and pushed to the SDK running in this tab, and to every other visitor on this page.
Flag
Public demo · Live demo environment
New checkout
demo-new-checkoutAccent colour demo-accent
Your browser
A demo storefront evaluating flags locally with @nanoflags/sdk
Trail Runner 2
Lightweight running shoe
$129
Step 1 of 3 · Shipping address
Anything you publish here is visible to every visitor. Resets to the default every 15 minutes.
Want this in your own app? Start free — no cardOne change, end to end
Every flag change follows the same path as a code change. Each step leaves an artefact you can point to.
Edit targeting, values or rollout. Nothing reaches users until it's published.
draft · checkout-v2
Scenario checks run saved contexts against the draft and compare them with the expected results. A failing check blocks publishing.
12 / 12 passed
A teammate reviews the diff. Authors and editors can't approve their own change.
approved · not an author
The change becomes an immutable revision, signed with Ed25519 and pushed over live connections.
r184 · kid k2
SDKs check the signature, swap in the new config, and report which revision they loaded. Gaps stay visible as “unknown”.
signature valid
Roll back by restoring any earlier revision. Every step is in the audit log.
Delivery
Published changes travel over WebSockets on Cloudflare's network and arrive in SDKs in about a fifth of a second. Your app evaluates flags locally, so a slow network never slows a request, and a lost connection leaves the last verified config running.
Publish
postgres commit
Sign
Ed25519
Edge
WebSocket push
SDK
verify → evaluate
import { createClient } from "@nanoflags/sdk";
const flags = createClient({
sdkKey: process.env.NANOFLAGS_SDK_KEY!,
baseUrl: "https://edge.nanoflags.io",
service: "checkout-api",
});
await flags.ready(); // never rejects
const on = flags.boolean("checkout-v2", false, { key: user.id, region: "EU" });
// Evaluated locally. Falls back to false only if no config has ever loaded.import { createClient } from "@nanoflags/sdk";
import { NanoFlagsProvider, useFlag } from "@nanoflags/sdk/react";
const client = createClient({ sdkKey: "nf_pub_…", baseUrl: "https://edge.nanoflags.io", service: "web" });
export function App({ user }) {
return (
<NanoFlagsProvider client={client} context={{ key: user.id }}>
<Checkout />
</NanoFlagsProvider>
);
}
function Checkout() {
const v2 = useFlag("checkout-v2", false);
return v2 ? <NewCheckout /> : <OldCheckout />;
}import { OpenFeature } from "@openfeature/server-sdk";
import { createClient } from "@nanoflags/sdk";
import { NanoFlagsProvider } from "@nanoflags/openfeature-provider/server";
const nanoflags = createClient({ sdkKey: process.env.NANOFLAGS_SDK_KEY!, baseUrl: "https://edge.nanoflags.io" });
await OpenFeature.setProviderAndWait(new NanoFlagsProvider({ client: nanoflags }));
const on = await OpenFeature.getClient().getBooleanValue("checkout-v2", false, { targetingKey: user.id });npm i -g @nanoflags/cli
nanoflags scenarios run --source draft # gate a publish in CI
nanoflags refs scan . --repo acme/web # find flag references
nanoflags export --out project.json # take everything with youTrust, but verify
Run the bucketing engine in your browser, see exactly what a browser key receives, and read the account controls. The public signing keys are at /v1/keys.
One engine runs at the edge, in the SDK, in the CLI and in CI. Type any user key: the result is computed in your browser with the same code.
hash("checkout-v2", "user_1") → 40.61 < 50 ✓ · rollout 50%
A browser key receives only client-exposed flags and the segments they use. Server rules stay on your servers.
TOTP
MFA with recovery codes; enforce it for admins
RLS
Row-level security on every table, checked by an automated cross-organization isolation suite
1 h
Hourly backups and a public status page with incidents
≈1 min
A revoked key is refused at the edge within about a minute
No lock-in
The parts that run in your code are open source, and your data is always yours to take.
LICENSEApache-2.0
The SDK, evaluation engine, CLI and GitHub Action are Apache-2.0. Read every line that runs in your app.
SDK on GitHubWrite your flag calls against the OpenFeature standard API; NanoFlags evaluates them locally underneath.
OpenFeature guideDownload a whole project (flags, segments, environments, drafts, scenarios and published bundles) as one JSON file from the dashboard, or run nanoflags export in CI.
CLI referenceIf we're unreachable, your app keeps serving the last config it verified. You stay in control.
In your workflow
Install the CLI
npm i -g @nanoflags/cliA PR comment with the flag states a change touches, code references, and a “NanoFlags scenarios” check.
nanoflags[bot] commented
Flags read in this pull request
| flag | Staging | Production |
|---|---|---|
| checkout-v2 | on · 50% · r212 | on · 25% · r184draft differs |
| new-pricing-page | off · r212 | off · r184 |
NanoFlags scenarios — success
Pricing
Start free on one project. Prices are public, limits never block your apps from reading flags, and there's a 14-day refund.
$0
Try the full workflow on one project.
$149/mo
Required reviews and scenario checks for production.
$499/mo
Several products, unlimited members, audit export.
Custom
Security review, custom limits and contract terms.
Who you're trusting
NanoFlags launched in 2026. We don't have customer logos to show you yet, and we won't invent them. What we can give you is everything you need to check us: live performance data, open-source code, a public security page and our registered company details.
Free for one project. No per-evaluation billing. Export any time.