Enhanced Feature Flags Toolkit Built on Vercel’s Flags SDK
A streamlined toolkit that brings enhanced developer experience, CLI tooling, and shadcn/ui-compatible component registry distribution to feature flags, while preserving the security and performance benefits of the “flags as code” approach.
Quick Links
Fargo Flags solves the feature flag dilemma by building on Vercel’s Flags SDK foundation – keeping your flag logic in your codebase where it belongs, while adding the tooling and convenience features that make adoption effortless.
Each feature flag lives in its own TypeScript file with complete type safety, Zod validation, and clear decision logic.
Create flags instantly with guided prompts – no manual boilerplate or registry management required.
All flag decisions run securely on the server, with client-safe values automatically filtered and hydrated.
Clean hooks and declarative components make flag usage intuitive and maintainable.
Install via familiar shadcn/ui-style commands – no complex setup or configuration files.
Override flags easily in unit tests and Storybook stories with dedicated test providers.
Consistency checker prevents configuration drift and catches issues before deployment.
Built on Solid Foundation: Leverages Vercel’s proven “flags as code” architecture for security and performance.
Developer Experience First: Interactive CLI, automatic registry management, and comprehensive TypeScript support eliminate common pain points.
No Vendor Lock-in: Your flag logic stays in your codebase – easy to adopt, easy to migrate away from if needed.
Production Ready: Used in real applications with server-side resolution, parallel flag evaluation, and comprehensive error handling.
Define flags → Wizard updates registry → Server resolves via resolveAllFlags(ctx)
; pickClientFlags()
filters public flags → Hydrate <FlagsProvider>
→ Use useFlag('key')
or <Flag when="key" />
.
npx shadcn@latest add https://flags.griffen.codes/r/flags-core
npx shadcn@latest add https://flags.griffen.codes/r/flags-cli
{
"scripts": {
"flags:new": "tsx scripts/create-flag.ts",
"flags:check": "tsx scripts/check-flags-registry.ts"
}
}
// app/layout.tsx
import { resolveAllFlags, pickClientFlags } from "@/lib/flags/runtime";
import { FlagsProvider } from "@/components/flags/flags-provider";
export default async function RootLayout({ children }) {
const serverFlags = await resolveAllFlags({
getUser: async () => getCurrentUser(),
getWorkspace: async () => getCurrentWorkspace(),
});
const clientFlags = pickClientFlags(serverFlags);
return (
<html>
<body>
<FlagsProvider flags={clientFlags}>{children}</FlagsProvider>
</body>
</html>
);
}
pnpm flags:new
import { useFlag } from "@/components/flags/flags-provider";
import { Flag } from "@/components/flags/flag";
function Dashboard() {
const isPremium = useFlag("enable-premium-features");
return (
<div>
{isPremium && <PremiumFeatures />}
<Flag when="enable-premium-features" fallback={<UpgradePrompt />}>
<PremiumFeatures />
</Flag>
</div>
);
}
pnpm flags:check
client.public: true
.serialize()
hooks can sanitize values for client hydration.Flag Definition:
export default defineFlag({
key: "enable-premium-features",
schema: z.boolean(),
defaultValue: false,
client: { public: true },
async decide(ctx) {
const user = await ctx.getUser?.();
return user?.plan === "premium";
},
});
Component Usage:
function Dashboard() {
const isPremium = useFlag("enable-premium-features");
return (
<div>
<Flag when="enable-premium-features" fallback={<UpgradePrompt />}>
<PremiumFeatures />
</Flag>
</div>
);
}
Perfect for Next.js applications that need feature flags without vendor lock-in or complex external dependencies.