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:

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

FlagDescription
auth.credentialCredential authentication method. Set to false to disable, use CredentialOption.EMAIL_AND_PASSWORD for email & password, or CredentialOption.MAGIC_LINK for magic links.
auth.socialProviders.GOOGLEEnable or disable Google OAuth (requires Google OAuth setup).
auth.socialProviders.GITHUBEnable or disable GitHub OAuth (requires GitHub OAuth setup).
packages/utils/src/constants/features.ts
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.

packages/utils/src/constants/features.ts
export const features: Features = {
  auth: {
    credential: false,
  },
};

Billing Flags

FlagDescription
billingSet to false to disable billing completely.
billing.subscriptionSet to false to disable subscriptions.
billing.subscription.trialDaysNumber of free trial days (or false to disable trials).
billing.subscription.allowChangeSubscriptionAllow users to upgrade/downgrade plans.
billing.creditsSet to false to disable the credit system.
billing.credits.lookupKeyStripe product lookup key for credit purchases.
billing.credits.welcomeCredits granted on signup (in cents, 500 = $5).
billing.credits.subscription.trialGrantGrant prorated credits during trial.
billing.credits.subscription.renewalGrantGrant 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:

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

packages/utils/src/constants/features.ts
export const features: Features = {
  billing: false,
};

Example 2: Disable Subscriptions

packages/utils/src/constants/features.ts
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

packages/utils/src/constants/features.ts
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

packages/utils/src/constants/features.ts
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.