Skip to main content

Feature Toggles

Feature toggles (also known as feature flags) allow you to decouple feature deployment from code deployment. You can release code to production but keep the feature hidden or structurally disabled until you are ready to turn it on for specific tenants, or globally.

The system now supports multiple types of feature toggles, allowing for dynamic runtime configuration beyond simple on/off switches:

  • Boolean: Standard enabled/disabled flag.
  • String: Text value configuration.
  • Number: Numeric value configuration.
  • JSON: Complex object configuration.

Required Role: Super Admin

Creating a Global Feature Toggle

Global feature toggles are the default state for a feature across the entire system.

Creating a global feature toggle

  1. Open Admin → Feature Toggles.
  2. Click Create Feature Toggle.

Creating a global feature toggle

  1. Enter a Identifier (key) for the toggle. This is the identifier used in the code (e.g., checkout_new_flow).
  2. Enter a Name for the toggle. This is the name that will be displayed in the UI.
  3. Provide a Description to explain what this toggle controls.
  4. Select the Type (Boolean, String, Number, or JSON).
  5. Set the initial Value based on the selected type:
  • For Boolean type: Choose true or false

  • For String type: Enter any text value

  • For Number type: Enter a numeric value (e.g., 10)

  • For JSON type: Use the built-in JSON builder with two tabs:

    Builder (visual editor): Creating a global feature toggle

    RAW (text editor): Creating a global feature toggle

    For other types, use the simple input field: Creating a global feature toggle

  1. Click Create.

Managing Overrides

You can override the global value of a feature toggle for specific tenants. This allows for gradual rollouts, beta testing with specific customers, or tenant-specific configuration.

Feature toggle overrides

  1. Navigate to the Overrides tab within the Feature Toggles section or select a specific Feature Toggle.
  2. Locate the Overrides section.
  3. Select the Tenant you want to apply the override to.
  4. Set the Value for this specific context (e.g., change a boolean to Enabled, or adjust a Number value). Feature toggle overrides - Value Input Feature toggle overrides - Value Input
  5. Save the override.

Using Feature Toggles in Code

Once a toggle is created, you can use it in your backend or frontend code to conditionally execute logic or render components.

React (Frontend)

Components

Use the FeatureFlag component (or FeatureGuard) to conditionally render UI elements. Note that FeatureGuard determines visibility based on Boolean toggles (truthy check).

import { FeatureFlag } from "@saasframe/core";

export const MyComponent = () => {
return (
<div>
<h1>Welcome</h1>
<FeatureFlag name="payment_new_flow">
<NewFeatureComponent />
</FeatureFlag>
</div>
);
};

Hooks

Use typed hooks for accessing toggle values in your components.

Boolean Toggle:

import { useFeatureFlagBoolean } from "@saasframe/core";

export const MyComponent = () => {
const { enabled, isLoading } = useFeatureFlagBoolean({ id: "payment_new_flow" });

if (isLoading) return <Loading />;
if (enabled) return <NewFeatureComponent />;
return <OldComponent />;
};

String Toggle:

import { useFeatureFlagString } from "@saasframe/core";

export const BrandingComponent = () => {
const { value } = useFeatureFlagString({ id: "brand_header_color" });
return <div style={{ color: value }}>Header</div>;
};

Number Toggle:

import { useFeatureFlagNumber } from "@saasframe/core";

export const ListComponent = () => {
const { value } = useFeatureFlagNumber({ id: "items_per_page" });
// use value (number) for pagination
};

JSON Toggle:

import { useFeatureFlagJson } from "@saasframe/core";

export const ConfigComponent = () => {
const { value } = useFeatureFlagJson<{ showSidebar: boolean }>({ id: "ui_config" });
// value is typed as { showSidebar: boolean } or null/unknown
};

Service (Backend)

Use the FeatureTogglesService to retrieve configuration values.

Boolean Toggle:

import { FeatureTogglesService } from "@saasframe/core";

export class CheckoutService {
constructor(private readonly featureToggles: FeatureTogglesService) {}

async processCheckout(tenantId: string) {
const isEnabledResult = await this.featureToggles.getBoolConfig("enable_new_checkout_flow", tenantId);
if (isEnabledResult.ok && isEnabledResult.value) {
// execute new checkout flow logic
}
}
}

String Toggle:

// Inside your service method
async getTheme(tenantId: string) {
const themeResult = await this.featureToggles.getStringConfig("checkout_theme_mode", tenantId);
const theme = themeResult.ok ? themeResult.value : "light";
}

Number Toggle:

// Inside your service method
async getCartLimit(tenantId: string) {
const limitResult = await this.featureToggles.getNumberConfig("max_cart_items", tenantId);
const limit = limitResult.ok ? limitResult.value : 10;
}

JSON Toggle:

// Inside your service method
interface PaymentProviderConfig {
provider: string;
retries: number;
}

async getPaymentConfig(tenantId: string) {
const configResult = await this.featureToggles.getJsonConfig<PaymentProviderConfig>("payment_provider_settings", tenantId);
if (configResult.ok) {
const settings = configResult.value;
}
}

Error Handling

When retrieving toggle values manually (e.g., via Service or API), the result uses a Result<T> pattern.

type Result<T> =
| { ok: true; value: T; resolution: ResolutionMetadata }
| { ok: false; error: ToggleError; resolution: ResolutionMetadata };

Common error codes:

  • MISSING_TOGGLE: The requested identifier does not exist.
  • TYPE_MISMATCH: The toggle exists but is not of the requested type (e.g., requested String but toggle is Boolean).
  • INVALID_VALUE: The resolved value is not valid for the requested type (e.g. null for a non-nullable type or wrong primitive type).

Automating Feature Toggles with the CLI

You can manage feature toggles via the CLI for CI/CD pipelines or scripted setups.

Seeding from JSON file

You can seed default feature toggles from a file (e.g., for initializing a new environment).

yarn saasframe feature-toggles seed-defaults --path ./toggles.json

Overriding with commands

You can script the application of overrides for specific tenants.

yarn saasframe feature-toggles override-set-value \
--identifier "checkout_new_flow" \
--value true \
--tenantId <tenant-id>

For a full list of commands, see the CLI Feature Toggles section.