unleashsdk
Use this skill when implementing feature flags and gradual rollouts in ColdBox/BoxLang using the unleashsdk module. Covers UnleashClient configuration, isEnabled() checks, getVariant() for A/B testing, custom context, gradual rollout strategies, and production patterns for safe feature releases.
UnleashSDK Skill
When to Use This Skill
Load this skill when:
- Enabling/disabling features at runtime without redeployment
- Rolling out features gradually to a percentage of users
- Running A/B tests or controlled experiments
- Creating killswitches for risky features
- Targeting feature flags to specific user segments
Installation
box install unleashsdk
Configuration
config/modules/unleashsdk.cfc
function configure() {
return {
// Unleash server URL
url : getSystemSetting( "UNLEASH_URL", "https://unleash.example.com/api" ),
// Client API token
apiToken : getSystemSetting( "UNLEASH_TOKEN", "" ),
// Application identifier — shown in Unleash UI
appName : getSystemSetting( "APP_NAME", "myapp" ),
// Environment (matches Unleash environment activation)
environment: getSystemSetting( "APP_ENV", "production" ),
// How often to sync flags from server (seconds)
refreshInterval : 15,
// Cache TTL (seconds) — use cached values when server unreachable
cacheTTL : 60
}
}
Core API
Injection
property name="unleash" inject="UnleashClient@unleashsdk";
Check if a Feature is Enabled
// Simple check
if ( unleash.isEnabled( "new-dashboard" ) ) {
// render new dashboard
}
// With context (user ID, session ID, properties)
if ( unleash.isEnabled( "beta-checkout", {
userId : security.getCurrentUser().getId(),
sessionId : session.id,
properties: {
role : security.getCurrentUser().getRole(),
plan : security.getCurrentUser().getPlan()
}
} ) ) {
// show beta checkout flow
}
Get a Variant (A/B Testing)
var variant = unleash.getVariant( "checkout-button-color", {
userId : security.getCurrentUser().getId()
} )
// variant.name = "blue" | "green" | "disabled"
// variant.enabled = true/false
// variant.payload = { type: "string", value: "#0070f3" }
if ( variant.enabled ) {
prc.buttonColor = variant.payload.value
} else {
prc.buttonColor = "default"
}
Production Patterns
Feature Flag in a Handler
function checkout( event, rc, prc ) {
var userId = security.getCurrentUser().getId()
// Feature flag controls which checkout version to render
if ( unleash.isEnabled( "new-checkout-v2", { userId: userId } ) ) {
prc.layout = "v2"
event.setView( "checkout/v2/index" )
} else {
prc.layout = "v1"
event.setView( "checkout/v1/index" )
}
}
Gradual Rollout Service
class FeatureService {
property name="unleash" inject="UnleashClient@unleashsdk";
boolean function useNewSearch() {
return unleash.isEnabled( "new-search-engine", {
userId : security.getCurrentUser().getId(),
sessionId : session.id
} )
}
struct function getCheckoutVariant() {
var variant = unleash.getVariant( "checkout-experiment", {
userId : security.getCurrentUser().getId()
} )
return {
name : variant.enabled ? variant.name : "control",
config : variant.enabled ? variant.payload : {}
}
}
}
Killswitch / Emergency Disable
function run( event, rc, prc ) {
if ( !unleash.isEnabled( "data-export-feature" ) ) {
event.renderData(
type = "json",
statusCode = 503,
data = { error: "This feature is temporarily disabled." }
)
return
}
// ... proceed with export
}
Automated A/B Test Tracking
function trackAndRoute( event, rc, prc ) {
var variant = unleash.getVariant( "pricing-page", {
userId : security.getCurrentUser().getId()
} )
// Record which variant the user saw
analyticsService.track( "pricing_variant_shown", {
userId : security.getCurrentUser().getId(),
variant : variant.name
} )
if ( variant.name == "v2" ) {
event.setView( "pricing/v2" )
} else {
event.setView( "pricing/v1" )
}
}
Best Practices
- Always provide a default —
isEnabled()returnsfalseif the server is unreachable; design safe defaults - Use user context for consistent per-user bucketing in gradual rollouts
- Use
getVariant()for experiments, not justisEnabled()— variants carry payload and support multi-arm tests - Store the API token in an environment variable — never commit it to source control
- Use feature flags as killswitches for risky features — wrap expensive or experimental code paths
- Clean up stale flags — remove flags from code once a rollout is complete (100% or 0%)
- Test the
falsepath — ensure the application works correctly when a flag is disabled
Documentation
- unleashsdk: https://github.com/coldbox-modules/unleashsdk
- Unleash feature flags: https://docs.getunleash.io