Feature Flags
Learn how to implement and use feature flags in Shipkit to enable/disable features dynamically and manage feature rollouts effectively.
Feature Flags
Shipkit uses a simple, clean feature flag system based on environment variables.
How It Works
The src/config/features-config.ts
file detects which features are enabled based on your environment variables and generates build-time flags:
- Build-time flags - Only enabled features are injected into the client bundle as
NEXT_PUBLIC_FEATURE_*
with string value "true" - Disabled features - Are not included in the environment at all (undefined)
This allows natural boolean checks: if (env.NEXT_PUBLIC_FEATURE_STRIPE_ENABLED) { ... }
Usage
Client-side
import { env } from "@/env";
if (env.NEXT_PUBLIC_FEATURE_STRIPE_ENABLED) {
// Stripe logic - only runs when feature is actually enabled
}
Build-time (Next.js config)
import { buildTimeFeatures } from "@/config/features-config";
if (buildTimeFeatures.PAYLOAD_ENABLED) {
// Configure payload at build time
}
Feature Detection Rules
Features are automatically enabled when their required environment variables are present:
- Database:
DATABASE_URL
- Stripe:
STRIPE_SECRET_KEY
+NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
- Auth providers: Provider ID + secret (e.g.,
AUTH_GITHUB_ID
+AUTH_GITHUB_SECRET
) - Services: API key (e.g.,
OPENAI_API_KEY
)
Enable/Disable Flags
Some features can be explicitly controlled:
ENABLE_PAYLOAD=true
- Enable Payload CMSBETTER_AUTH_ENABLED=true
- Enable Better AuthDISABLE_MDX=true
- Disable MDX supportDISABLE_PWA=true
- Disable PWA
Adding New Features
-
Add detection logic to the
features
object infeatures-config.ts
:const features = { // Single variable check myFeature: () => EnvChecker.has("MY_API_KEY"), // Multiple variable check myAuthProvider: () => EnvChecker.has("MY_CLIENT_ID", "MY_CLIENT_SECRET"), };
-
The build and server flags will be generated automatically
-
Add corresponding env vars to
env.ts
for type safety
EnvChecker Utility Methods
EnvChecker.has(...names)
- Check if all variables exist (supports single or multiple)EnvChecker.hasAny(...names)
- Check if any variable existsEnvChecker.isEnabled(name)
- Check if variable is enabled (true/1/yes/on
)
Benefits
- Clean: Simple object-based configuration
- Type-safe: Integrated with T3 Env validation
- Flexible: Supports
true/1/yes/on
andfalse/0/no/off
values - Automatic: Flags generated based on available environment variables
- Consistent: Single
has()
method for all variable checks