Feature Flags
Feature flags allow you to enable or disable certain features in your application.
Enabling or Disabling Features
All features are enabled by default. You can easily opt out of a feature by changing its value in the configuration file.
The feature flags are defined in packages/utils/src/constants/features.ts:
export const features: Features = {
auth: {
credential: CredentialOption.EMAIL_AND_PASSWORD, // Use email & password (alternatively, use CredentialOption.MAGIC_LINK)
socialProviders: {
[SocialProvider.GOOGLE]: true, // Enable Google OAuth
[SocialProvider.GITHUB]: true, // Enable GitHub OAuth
},
},
billing: {
subscription: {
plans, // The subscription plans are defined in `packages/utils/src/constants/billing.ts`
trialDays: 7, // Give the user 7 days trial
allowChangeSubscription: true, // Allow the user to change the subscription plan
},
credits: {
lookupKey: "credits",
welcome: 500, // Give the user free credits after registration (amount is in cents, 500 = $5)
subscription: {
trialGrant: true, // Grant the user credits during the trial period (prorated renewal grant: $30 monthly plan will be prorated to $7 for 7 days trial)
renewalGrant: true, // Increase the user's credits on subscription renewal with the subscription price
},
},
},
};Authentication Flags
| Flag | Description |
|---|---|
auth.credential | Credential authentication method. Set to false to disable, use CredentialOption.EMAIL_AND_PASSWORD for email & password, or CredentialOption.MAGIC_LINK for magic links. |
auth.socialProviders.GOOGLE | Enable or disable Google OAuth (requires Google OAuth setup). |
auth.socialProviders.GITHUB | Enable or disable GitHub OAuth (requires GitHub OAuth setup). |
Example 1: Magic Link and only Google OAuth
export const features: Features = {
auth: {
credential: CredentialOption.MAGIC_LINK,
socialProviders: {
[SocialProvider.GOOGLE]: true,
[SocialProvider.GITHUB]: false,
},
},
};Example 2: No Authentication
You should never disable authentication completely as it is required for the application to work properly.
export const features: Features = {
auth: {
credential: false,
},
};Billing Flags
| Flag | Description |
|---|---|
billing | Set to false to disable billing completely. |
billing.subscription | Set to false to disable subscriptions. |
billing.subscription.trialDays | Number of free trial days (or false to disable trials). |
billing.subscription.allowChangeSubscription | Allow users to upgrade/downgrade plans. |
billing.credits | Set to false to disable the credit system. |
billing.credits.lookupKey | Stripe product lookup key for credit purchases. |
billing.credits.welcome | Credits granted on signup (in cents, 500 = $5). |
billing.credits.subscription.trialGrant | Grant prorated credits during trial. |
billing.credits.subscription.renewalGrant | Grant credits on subscription renewal. |
For the credit system, you can configure the trial grants and renewal grants per plan and interval.
The GrantConfig type is used for both trial grants and renewal grants. It is defined in packages/utils/src/types/billing.ts:
export type GrantConfig =
| boolean // All plans: Grant the subscription price (YES/NO)
| number // All plans: Grant a fixed amount (amount is in cents, 500 = $5)
| {
// Per-plan config keyed by plan lookupKey (e.g., "pro", "ultimate")
// Plans not listed receive no credits
[K in PaidPlanLookupKey]:
| boolean // All intervals: Grant the subscription price (YES/NO)
| number // All intervals: Grant a fixed amount (amount is in cents, 500 = $5)
| {
[BillingInterval.MONTH]: boolean | number; // Month interval: Grant the subscription price (YES/NO) or a fixed amount (amount is in cents, 500 = $5)
[BillingInterval.YEAR]: boolean | number; // Year interval: Grant the subscription price (YES/NO) or a fixed amount (amount is in cents, 500 = $5)
};
};We aimed to make the configuration as flexible as possible. Switch business models without rewriting payment logic.
Example 1: Disable Billing
export const features: Features = {
billing: false,
};Example 2: Disable Subscriptions
export const features: Features = {
billing: {
subscription: false,
credits: {
lookupKey: "credits",
welcome: 500,
subscription: {
trialGrant: false,
renewalGrant: false,
},
},
},
};Example 3: No Welcome Credits and Renewal Grants
export const features: Features = {
billing: {
subscription: {
plans,
trialDays: 7,
allowChangeSubscription: true,
},
credits: {
lookupKey: "credits",
welcome: false,
subscription: {
trialGrant: true,
renewalGrant: false,
},
},
},
};Example 4: Custom Trial Grants and Renewal Grants
export const features: Features = {
billing: {
subscription: {
plans,
trialDays: 14, // 14 days trial
allowChangeSubscription: false, // Disable subscription plan changes
},
credits: {
lookupKey: "credits",
welcome: false, // No welcome credits
subscription: {
trialGrant: {
pro: {
[BillingInterval.MONTH]: 1000, // $10 ($30 plan price per month: `true` (prorated) would be $14 but we want give only $10)
[BillingInterval.YEAR]: true, // Prorated ($300 plan price per year -> $12 during the 14 days trial)
},
ultimate: true, // Prorated for both intervals
},
renewalGrant: {
pro: {
[BillingInterval.MONTH]: 2000, // $20 ($30 plan price per month: `true` would be $30 but we want give only $20)
[BillingInterval.YEAR]: true, // The subscription price
},
ultimate: true, // The subscription price for both intervals
},
},
},
},
};Usage in Code
import { features } from "@package/utils";
if (features.auth.credential) {
// Credential authentication is enabled
}
if (features.billing?.subscription) {
// Subscription features available
}
if (features.billing?.credits) {
// Credit system is active
}The application reacts dynamically to feature flag changes.
Components and API services check feature flags before rendering or executing.