Flipt
"Flipt: open-source, self-hosted feature flag platform with GitOps support, boolean and multivariate flags, and GRPC/REST APIs"
You are an expert in integrating Flipt for feature flag management. ## Key Points - key: dark-mode - key: checkout-experiment - key: beta-testers - key: all-users - **Separate namespaces per team or domain** — namespaces prevent flag key collisions and let teams manage their own flags independently without affecting others. - **Use batch evaluation when checking multiple flags** — a single batch request reduces network round-trips compared to individual calls, especially important when Flipt runs as a remote service.
skilldb get feature-flags-services-skills/FliptFull skill: 289 linesFlipt — Feature Flags
You are an expert in integrating Flipt for feature flag management.
Core Philosophy
Flipt exists for teams that want feature flags without vendor lock-in. It is fully open-source, self-hosted, and requires nothing beyond a database (even SQLite for small deployments). You own the data, control the infrastructure, and never worry about per-seat pricing, usage limits, or a third-party SaaS going down. The tradeoff is operational responsibility: you manage the deployment, backups, and availability of the Flipt service.
GitOps is the recommended way to manage flags in production. Flipt can sync flag definitions from a Git repository, making every flag change a pull request that is reviewable, auditable, and reversible. Developers propose flag changes in YAML, reviewers approve them, and Flipt's Git backend polls the repository and applies updates automatically. This workflow eliminates the risk of ad-hoc dashboard changes that no one can trace or undo.
Namespaces provide isolation without infrastructure duplication. Instead of running separate Flipt instances for each team or domain, use namespaces to partition flag definitions so that team A's flags cannot collide with or affect team B's flags. Combined with the API's namespace-scoped evaluation, this makes Flipt suitable for multi-team organizations without the cost of per-team infrastructure.
Anti-Patterns
- Forgetting to set
enabled: trueon a flag -- A flag can have fully configured rules and rollouts, but if the top-levelenabledfield is false, it always evaluates to its default (false for booleans, no variant). This is the most common "my flag isn't working" debugging issue. - Using inconsistent entity IDs for the same user -- Percentage rollouts are deterministic based on
entityId + flagKey. Passing email for one request and UUID for another means the same user gets inconsistent treatment assignments. - Making individual evaluation calls when batch evaluation is available -- Each evaluation is a network round-trip to the Flipt server. When checking multiple flags per request, use batch evaluation to reduce latency.
- Running Flipt without a durable database in production -- SQLite is fine for development, but production deployments should use PostgreSQL or MySQL for durability, backups, and concurrent access.
- Skipping the Git backend in favor of dashboard-only management -- Dashboard changes are convenient but unauditable. Without Git history, you cannot trace who changed a flag, when, or why -- and you cannot revert safely.
Overview
Flipt is an open-source, self-hosted feature flag platform that requires no external dependencies beyond a database. It supports boolean flags, multivariate flags with variants, percentage-based rollouts, segment-based targeting, and namespaces for multi-tenant or multi-team isolation. Flipt offers both gRPC and REST APIs, a built-in web UI, and a GitOps-native workflow where flag definitions can live in Git repositories and be synced declaratively. There is no SaaS vendor dependency — you own the entire stack.
Setup & Configuration
Self-Hosted Deployment
# docker-compose.yml
version: "3.9"
services:
flipt:
image: flipt/flipt:latest
ports:
- "8080:8080" # HTTP API + UI
- "9000:9000" # gRPC API
volumes:
- ./flipt-config.yml:/etc/flipt/config.yml
- flipt_data:/var/opt/flipt
environment:
FLIPT_LOG_LEVEL: info
FLIPT_DB_URL: "file:/var/opt/flipt/flipt.db" # SQLite default
volumes:
flipt_data:
Node.js SDK (REST)
import { FliptClient } from "@flipt-io/flipt";
const flipt = new FliptClient({
url: process.env.FLIPT_URL || "http://localhost:8080",
authToken: process.env.FLIPT_AUTH_TOKEN,
});
// Boolean flag evaluation
const boolResult = await flipt.evaluation.boolean({
namespaceKey: "default",
flagKey: "dark-mode",
entityId: user.id,
context: {
plan: user.plan,
region: user.region,
},
});
if (boolResult.enabled) {
enableDarkMode();
}
// Variant flag evaluation
const variantResult = await flipt.evaluation.variant({
namespaceKey: "default",
flagKey: "checkout-experiment",
entityId: user.id,
context: {
country: user.country,
},
});
// variantResult.variantKey: "control" | "streamlined" | "minimal"
renderCheckout(variantResult.variantKey);
Go SDK
package main
import (
"context"
"log"
"os"
flipt "go.flipt.io/flipt/sdk/go"
flipthttp "go.flipt.io/flipt/sdk/go/http"
)
func main() {
client := flipt.New(
flipthttp.NewTransport(os.Getenv("FLIPT_URL")),
)
result, err := client.Evaluation().Boolean(context.Background(), &flipt.EvaluationRequest{
NamespaceKey: "default",
FlagKey: "new-algorithm",
EntityId: "user-123",
Context: map[string]string{
"tier": "premium",
},
})
if err != nil {
log.Fatal(err)
}
if result.Enabled {
useNewAlgorithm()
}
}
Core Patterns
GitOps — Flags as Code
Flipt can sync flag definitions from a Git repository, making flags version-controlled and reviewable via pull requests.
# .flipt.yml at repo root — tells Flipt where to find flag definitions
version: "1.0"
# features/flags.yml
namespace: default
flags:
- key: dark-mode
name: Dark Mode
type: BOOLEAN_FLAG_TYPE
enabled: true
rollouts:
- segment:
key: beta-testers
value: true
- threshold:
percentage: 25
value: true
- key: checkout-experiment
name: Checkout Experiment
type: VARIANT_FLAG_TYPE
enabled: true
variants:
- key: control
name: Control
- key: streamlined
name: Streamlined Flow
- key: minimal
name: Minimal Flow
rules:
- segment: all-users
distributions:
- variant: control
rollout: 50
- variant: streamlined
rollout: 30
- variant: minimal
rollout: 20
segments:
- key: beta-testers
name: Beta Testers
match_type: ANY_MATCH_TYPE
constraints:
- type: STRING_COMPARISON_TYPE
property: plan
operator: eq
value: "enterprise"
- key: all-users
name: All Users
match_type: ALL_MATCH_TYPE
# Flipt config to enable Git backend
# /etc/flipt/config.yml
storage:
type: git
git:
repository: https://github.com/your-org/feature-flags.git
ref: main
poll_interval: 30s
authentication:
token:
access_token: ${GITHUB_TOKEN}
Namespaces for Multi-Team Isolation
// Team A flags
const teamAResult = await flipt.evaluation.boolean({
namespaceKey: "team-payments",
flagKey: "stripe-v2",
entityId: user.id,
context: {},
});
// Team B flags — completely isolated
const teamBResult = await flipt.evaluation.boolean({
namespaceKey: "team-notifications",
flagKey: "email-batching",
entityId: user.id,
context: {},
});
Batch Evaluation
const batchResult = await flipt.evaluation.batch({
requests: [
{
namespaceKey: "default",
flagKey: "dark-mode",
entityId: user.id,
context: { plan: user.plan },
},
{
namespaceKey: "default",
flagKey: "checkout-experiment",
entityId: user.id,
context: { country: user.country },
},
{
namespaceKey: "default",
flagKey: "new-pricing",
entityId: user.id,
context: {},
},
],
});
// batchResult.responses is an array matching the request order
const [darkMode, checkout, pricing] = batchResult.responses;
REST API Direct Usage
# Evaluate a boolean flag
curl -X POST http://localhost:8080/evaluate/v1/boolean \
-H "Content-Type: application/json" \
-d '{
"namespaceKey": "default",
"flagKey": "dark-mode",
"entityId": "user-123",
"context": {"plan": "pro"}
}'
# Evaluate a variant flag
curl -X POST http://localhost:8080/evaluate/v1/variant \
-H "Content-Type: application/json" \
-d '{
"namespaceKey": "default",
"flagKey": "checkout-experiment",
"entityId": "user-123",
"context": {"country": "US"}
}'
Best Practices
- Use GitOps for production flag management — storing flag definitions in Git gives you version history, pull request reviews, and rollback via
git revert. The Flipt Git backend polls automatically. - Separate namespaces per team or domain — namespaces prevent flag key collisions and let teams manage their own flags independently without affecting others.
- Use batch evaluation when checking multiple flags — a single batch request reduces network round-trips compared to individual calls, especially important when Flipt runs as a remote service.
Common Pitfalls
- Forgetting to set
enabled: trueon the flag — a flag can have rules and rollouts configured, but if the top-levelenabledfield is false, the flag always evaluates to its default (false for booleans, no variant for variant flags). - Entity ID inconsistency — percentage rollouts are deterministic based on
entityId + flagKey. If you pass different identifiers for the same user across requests (e.g., sometimes email, sometimes UUID), the user gets inconsistent treatment assignments.
Install this skill directly: skilldb add feature-flags-services-skills
Related Skills
ConfigCat
"ConfigCat: feature flags and remote config with percentage rollouts, targeting rules, config-as-code, and cross-platform SDKs"
Flagsmith
"Flagsmith: open-source feature flags, remote config, segments, environments, audit logs, self-hosted, REST API"
GrowthBook
"GrowthBook: open-source feature flags, A/B testing, Bayesian statistics, SDK, targeting, webhooks, self-hosted"
LaunchDarkly
"LaunchDarkly: feature flags, targeting rules, segments, experiments, metrics, Node/React SDK, bootstrap, streaming"
Split.io
"Split.io: feature delivery platform with feature flags, targeting, experimentation, traffic allocation, and metrics integration"
Statsig
"Statsig: feature gates, dynamic config, experiments/A/B tests, metrics, layers, Next.js SDK, server/client evaluation"