Getting Started with Feature Switches - j-fischer/rflib GitHub Wiki
Feature switches (also called feature flags or feature toggles) are an integral part of modern org development. They allow you to:
- Deploy features safely: Release code but keep features hidden until ready
- Enable A/B testing: Show different features to different user groups
- Manage integrations: Turn off external integrations during outages without deployments
- Control rollouts: Gradually enable features for specific users or groups
- Reduce deployment risk: Separate code deployment from feature activation
RFLIB's Feature Switch implementation is based on Custom Metadata Types but includes hierarchical configuration similar to Custom Settings, giving you the best of both worlds: metadata flexibility with user hierarchy.
- RFLIB installed in your org
- Understanding of Salesforce hierarchies: User → Profile → Public Group → Global
- System Administrator access to create Custom Metadata records

Step 1: Create a Feature Switch record in the Custom Metadata Type
Step 2: Set the scope (User, Profile, Public Group, or Global)
Step 3: Use the rflib_FeatureSwitch utility class to check the switch in your code

Feature switches are evaluated in the following hierarchical order. The first value found will be returned:
- User Level - Specific to individual users
- Public Group Level - For users in specific groups
- Profile Level - For users with specific profiles
- Global Level - Organization-wide default
Important Notes:
- Public Groups require direct membership (not role-based)
- Multiple groups are evaluated in alphabetical order by
DeveloperName - Default value is
falseif no configuration matches
Switch Name: "New_Dashboard_UI"
- Global: false (default)
- Profile (System Administrator): true
- User ([email protected]): true
Switch Name: "External_API_Enabled"
- Global: true (normal operation)
- During outage: Change Global to false
Switch Name: "Enhanced_Search"
- Global: false
- Public Group (Test_Group_A): true
- Public Group (Test_Group_B): false
Basic Usage:
// Simple check
if (rflib_FeatureSwitch.isTurnedOn('New_Feature')) {
// Execute new feature code
executeNewFeature();
} else {
// Execute legacy code
executeLegacyFeature();
}
// Alternative syntax
if (rflib_FeatureSwitch.isTurnedOff('Maintenance_Mode')) {
// Normal operation
processRequest();
}Real-world Example from Trigger Framework:
private static void dispatch(rflib_TriggerManager.Args args) {
List<TriggerHandlerInfo> handlers = getHandlers(args);
// Circuit breaker pattern
if (rflib_FeatureSwitch.isTurnedOff('All_Triggers')) {
LOGGER.warn('All Trigger Feature switch turned off, exiting trigger execution.');
return;
}
// Continue with normal processing...
}Integration Control Example:
public void syncWithExternalSystem(List<Account> accounts) {
if (rflib_FeatureSwitch.isTurnedOff('External_Sync_Enabled')) {
LOGGER.info('External sync disabled via feature switch');
return;
}
// Proceed with integration
externalApiService.syncAccounts(accounts);
}You can also use features switches on the client side. For LWC, use the following syntax:
import { isFeatureSwitchTurnedOn } from 'c/rflibFeatureSwitches';
handleSomeEvent(event) {
isFeatureSwitchTurnedOn('mySwitchName')
.then(isTurnedOn => {
if (isTurnedOn) {
// do something
}
});
}
In Aura components, add the feature switch component in the .cmp file.
<c:rflibFeatureSwitches aura:id="featureSwitches" />
In the controller or helper, you can then validate a feature switch with the following code snippet:
({
doInit: function(component, event, helper) {
var featureSwitches = component.find('featureSwitches');
featureSwitches.isFeatureSwitchTurnedOn('All_Triggers')
.then(function (isTurnedOn) {
logger.info('All_Triggers turned on? ' + isTurnedOn);
});
}
})
In Flow Builder, Global feature switches can easily be accessed using the Get Records element. See the screenshot below for a sample configuration.

If you would like to retrieve a full hierarchical feature switch value, that can be overwritten on a profile of user level, use the Apex Action displayed below.

Validation Rules can also be configured to consider feature switches. However, there is one limitation and that is that the Feature Switch must be mentioned by API name. This will make it more difficult to consider the hierarchy, therefore it is recommended to only use feature switches with a global scope in validation rules.
Below is an example of a formula using a feature switch, which is taken from the demo project:
$CustomMetadata.rflib_Feature_Switch__mdt.Data_Load_In_Progress.Turned_On__c = FALSE &&
TODAY() - Date_Listed__c > 15
Troubleshooting Steps:
- Check if user has a User-level setting overriding other levels
- Verify Public Group membership if using group-level switches
- Confirm Profile assignment matches the configured profile
- Remember: The hierarchy goes User → Group → Profile → Global
Common Causes:
- Custom Metadata not deployed to production
- Different user profiles/groups between environments
- Caching issues (rare, but metadata might need time to sync)
Solution: Ensure you're using the API name format:
$CustomMetadata.rflib_Feature_Switch__mdt.Switch_API_Name.Turned_On__c
✅ DO:
- Use descriptive switch names (
Enhanced_Search_V2vsFeature1) - Document your switches and their purpose
- Use Global-level switches for org-wide features used in Formulas
- Test switches in sandbox before production
- Remove obsolete switches after feature rollout
❌ DON'T:
- Create too many granular switches (management overhead)
- Forget to clean up temporary switches
- Rely on switches for security controls
- Create Your First Switch: Start with a simple global switch
- Test the Hierarchy: Try user-level overrides
- Monitor Usage: Check which switches are being evaluated
- Plan Cleanup: Set reminders to remove temporary switches
Related Topics:
- Trigger Framework - Uses feature switches
- Global Config Settings - Overall configuration
- Application Events - Track feature usage