A JavaScript SDK for Switcher API
Switcher Client JS is a feature-rich SDK for integrating Switcher API into your JS-based applications (Web, Node.js, Bun, Cloudflare Workers). It provides robust feature flag management with enterprise-grade capabilities.
- π Zero Latency: Local mode with snapshot files or in-memory for instant feature flag resolution
- π Hybrid Configuration: Silent mode with automatic fallback handling
- π§ͺ Testing Ready: Built-in stub implementation for comprehensive testing
- β‘ Performance Optimized: Throttling optimizes remote API calls to reduce bottlenecks in critical code paths
- π οΈ Developer Tools: Runtime snapshot updates without app restart and automatic sync with remote API
Get up and running with Switcher Client in 3 simple steps:
npm install switcher-clientimport { Client } from 'switcher-client';
// 1. Initialize the client
Client.buildContext({
url: 'https://api.switcherapi.com',
apiKey: '[YOUR_API_KEY]',
domain: 'My Domain',
component: 'MyApp',
environment: 'default'
});
// 2. Get a switcher instance
const switcher = Client.getSwitcher();
// 3. Check if a feature is enabled
const isFeatureEnabled = await switcher.isItOn('FEATURE01');
console.log('Feature enabled:', isFeatureEnabled);npm install switcher-clientThe context properties store all information regarding connectivity:
import { Client } from 'switcher-client';
// Required configuration
const config = {
apiKey: '[API_KEY]', // Switcher-API key for your component
environment: 'default', // Environment name ('default' for production)
domain: 'My Domain', // Your domain name
component: 'MyApp', // Your application name
url: 'https://api.switcherapi.com' // Switcher-API endpoint (optional)
};
Client.buildContext(config);
const switcher = Client.getSwitcher();| Parameter | Type | Required | Description |
|---|---|---|---|
domain |
string | β | Your Switcher domain name |
url |
string | Switcher API endpoint | |
apiKey |
string | API key for your component | |
component |
string | Your application name | |
environment |
string | Environment name (default: 'default' for production) |
Configure additional features for enhanced functionality:
Client.buildContext({
url, apiKey, domain, component, environment
}, {
local: true, // Enable local mode
freeze: false, // Prevent background updates
logger: true, // Enable request logging
snapshotLocation: './snapshot/', // Snapshot files directory
snapshotAutoUpdateInterval: 300, // Auto-update interval (seconds)
snapshotWatcher: true, // Monitor snapshot changes
silentMode: '5m', // Fallback timeout
restrictRelay: true, // Relay restrictions in local mode
regexSafe: true, // Prevent reDOS attacks
certPath: './certs/ca.pem' // SSL certificate path
});| Option | Type | Description |
|---|---|---|
local |
boolean | Use only snapshot files/in-memory (no API calls) |
freeze |
boolean | Disable background cache updates with throttling |
logger |
boolean | Enable logging for debugging (Client.getLogger('KEY')) |
snapshotLocation |
string | Directory for snapshot files |
snapshotAutoUpdateInterval |
number | Auto-update interval in seconds (0 = disabled) |
snapshotWatcher |
boolean | Watch for snapshot file changes |
silentMode |
string | Fallback timeout (e.g., '5s', '2m', '1h') |
restrictRelay |
boolean | Enable relay restrictions in local mode |
regexSafe |
boolean | Protection against reDOS attacks |
regexMaxBlackList |
number | Max cached regex failures |
regexMaxTimeLimit |
number | Regex timeout in milliseconds |
certPath |
string | Path to SSL certificate file |
Security Note:
regexSafeprevents ReDoS attacks. Keep this enabled in production.
Multiple ways to check if a feature is enabled:
const switcher = Client.getSwitcher();
// π Synchronous (local mode only)
const isEnabled = switcher.isItOn('FEATURE01'); // Returns: boolean
const isEnabledBool = switcher.isItOnBool('FEATURE01'); // Returns: boolean
const detailResult = switcher.detail().isItOn('FEATURE01'); // Returns: { result, reason, metadata }
const detailDirect = switcher.isItOnDetail('FEATURE01'); // Returns: { result, reason, metadata }
// π Asynchronous (remote/hybrid mode)
const isEnabledAsync = await switcher.isItOn('FEATURE01'); // Returns: Promise<boolean>
const isEnabledBoolAsync = await switcher.isItOnBool('FEATURE01', true); // Returns: Promise<boolean>
const detailResultAsync = await switcher.detail().isItOn('FEATURE01'); // Returns: Promise<SwitcherResult>
const detailDirectAsync = await switcher.isItOnDetail('FEATURE01', true); // Returns: Promise<SwitcherResult>Load information into the switcher using prepare() when input comes from different parts of your code:
// Prepare the switcher with input data
await switcher.checkValue('USER_1').prepare('FEATURE01');
// Execute the check
const result = await switcher.isItOn();Fast method that includes everything in a single call:
const result = await switcher
.defaultResult(true) // π‘οΈ Fallback result if API is unavailable
.throttle(1000) // β‘ Cache result for 1 second
.checkValue('User 1') // π€ User-based strategy
.checkNetwork('192.168.0.1') // π Network-based strategy
.isItOn('FEATURE01');Perfect for critical code blocks requiring zero-latency. API calls are scheduled after the throttle time:
const switcher = Client.getSwitcher();
// Cache result for 1 second
const result = await switcher
.throttle(1000)
.isItOn('FEATURE01');Subscribe to error events to capture issues during throttled execution:
Client.subscribeNotifyError((error) => {
console.error('Switcher error:', error);
});Force specific switchers to resolve remotely while running in local mode. Ideal for features requiring remote validation (e.g., Relay Strategies):
const switcher = Client.getSwitcher();
// Force remote resolution for this specific call
const result = await switcher.remote().isItOn('FEATURE01');Bypass switcher configuration for testing scenarios. Perfect for validating both enabled and disabled states:
// β
Force feature to be enabled
Client.assume('FEATURE01').true();
const result = switcher.isItOn('FEATURE01'); // Returns: true
// β Force feature to be disabled
Client.assume('FEATURE01').false();
const result = switcher.isItOn('FEATURE01'); // Returns: false
// π Reset to normal behavior
Client.forget('FEATURE01');
const result = switcher.isItOn('FEATURE01'); // Returns: actual API/snapshot result// Add custom metadata to simulate Relay responses
Client.assume('FEATURE01')
.false()
.withMetadata({ message: 'Feature is disabled' });
const response = await switcher.detail().isItOn('FEATURE01');
console.log(response.result); // false
console.log(response.metadata.message); // "Feature is disabled"import { StrategiesType } from 'switcher-client';
// β
True only for specific value
Client.assume('FEATURE01')
.true()
.when(StrategiesType.VALUE, 'USER_1');
const resultUser1 = switcher.checkValue('USER_1').isItOn('FEATURE01'); // true
const resultUser2 = switcher.checkValue('USER_2').isItOn('FEATURE01'); // false
// β
True for multiple values
Client.assume('FEATURE01')
.true()
.when(StrategiesType.NETWORK, ['192.168.1.1', '192.168.1.2']);
const resultNetwork1 = switcher.checkNetwork('192.168.1.1').isItOn('FEATURE01'); // true
const resultNetwork2 = switcher.checkNetwork('192.168.1.3').isItOn('FEATURE01'); // falseEnable test mode to prevent snapshot file locking during automated testing:
// Add this to your test setup files
Client.testMode();π‘ Tip: This prevents the Switcher Client from locking snapshot files even after test execution completes.
Validate feature flag during startup to catch configuration issues early:
try {
await Client.checkSwitchers(['FEATURE01', 'FEATURE02', 'CRITICAL_FEATURE']);
console.log('β
All switchers configured correctly');
} catch (error) {
console.error('β Configuration issues found:', error.message);
process.exit(1);
}This feature validates using the current context and throws an exception if any Switcher Keys are not properly configured.
Load a local copy of your configuration to eliminate latency when local mode is activated:
// Basic snapshot loading
await Client.loadSnapshot();
// Load snapshot and enable auto-watching
await Client.loadSnapshot({ watchSnapshot: true });
// Fetch remote snapshot and enable auto-watching
await Client.loadSnapshot({ watchSnapshot: true, fetchRemote: true });Monitor snapshot changes and implement custom actions:
Client.watchSnapshot({
success: () => console.log('β
In-memory snapshot updated'),
reject: (err) => console.error('β Snapshot update failed:', err)
});Enable snapshot monitoring through client configuration:
Client.buildContext(
{ domain, component, environment },
{
local: true,
snapshotLocation: './snapshot/',
snapshotWatcher: true // ποΈ Enable automatic monitoring
}
);Check if your snapshot is up to date with the remote domain:
try {
const versionInfo = await Client.checkSnapshot();
console.log('Snapshot version info:', versionInfo);
} catch (error) {
console.error('Version check failed:', error);
}π‘ Use Case: Perfect for external processes that manage snapshot files independently.
Run the SDK in local mode (zero latency) while keeping snapshots automatically updated:
// Update every 3 seconds (3000 milliseconds)
Client.scheduleSnapshotAutoUpdate(3000, {
success: (updated) => console.log('Snapshot updated', updated),
reject: (err: Error) => console.log(err)
});Client.buildContext(
{ domain, component, environment },
{
local: true,
snapshotAutoUpdateInterval: 60 // π Update every 60 seconds
}
);