A Deno SDK for Switcher API
Switcher Client Deno (former Switcher4Deno) is a feature-rich SDK for integrating Switcher API into your Deno applications. 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
- Deno: Version 1.4x or above
- Required Permissions:
--allow-read --allow-write --allow-net
// Via JSR (Recommended)
import { Client } from "@switcherapi/switcher-client-deno@[VERSION]";
// Via deno.land
import { Client } from 'https://deno.land/x/switcher4deno@v[VERSION]/mod.ts';import { Client } from "@switcherapi/switcher-client-deno";
// 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('FEATURE01');
// 3. Check if a feature is enabled
const isEnabled = await switcher.isItOn();
console.log('Feature enabled:', isEnabled);| 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 |
⚠️ Note on regexSafe: This feature protects against reDOS attacks but uses Web Workers, which are incompatible with compiled executables.
Simple on/off checks for feature flags:
// Non-persisted switcher instance
const switcher = Client.getSwitcher();
// Persisted switcher instance
const switcher = Client.getSwitcher('FEATURE01');
// 🚀 Synchronous (local mode only)
const isEnabled = switcher.isItOn(); // Returns: boolean
const isEnabledBool = switcher.isItOnBool(); // Returns: boolean
const detailResult = switcher.detail().isItOn(); // Returns: { result, reason, metadata }
const detailDirect = switcher.isItOnDetail(); // Returns: { result, reason, metadata }
// 🌐 Asynchronous (remote/hybrid mode)
const isEnabledAsync = await switcher.isItOn(); // Returns: Promise<boolean>
const isEnabledBoolAsync = await switcher.isItOnBool(true); // Returns: Promise<boolean>
const detailResultAsync = await switcher.detail().isItOn(); // Returns: Promise<SwitcherResult>
const detailDirectAsync = await switcher.isItOnDetail(true); // Returns: Promise<SwitcherResult>Prepare context data before evaluation:
// Prepare input in advance
await switcher.checkValue('USER_1').prepare('FEATURE01');
const result = await switcher.isItOn();
// Or chain preparations
await switcher
.checkValue('premium_user')
.checkNetwork('192.168.1.0/24')
.prepare('ADVANCED_FEATURE');Complex feature flag evaluation with multiple strategies:
const result = await switcher
.defaultResult(true) // Fallback value if API fails
.throttle(1000) // Cache result for 1 second
.checkValue('User 1') // VALUE strategy
.checkNetwork('192.168.0.1') // NETWORK strategy
.isItOn('FEATURE01');Reduce API calls for high-frequency checks:
const switcher = Client.getSwitcher();
// Cache result for 1 second
const result = await switcher
.throttle(1000)
.isItOn('FEATURE01');
// Handle throttling errors
Client.subscribeNotifyError((error) => {
console.error('Switcher error:', error);
});Override local mode for specific switchers:
// Force remote resolution even in local mode
const result = await switcher
.remote()
.isItOn('CRITICAL_FEATURE');This is useful for:
- Relay strategies requiring remote calls
- Critical features that must be resolved remotely
- Real-time configuration updates
Mock feature flag responses for comprehensive testing:
// Simple true/false mocking
Client.assume('FEATURE01').true();
console.log(switcher.isItOn('FEATURE01')); // Always returns true
Client.assume('FEATURE01').false();
console.log(switcher.isItOn('FEATURE01')); // Always returns false
// Reset to normal behavior
Client.forget('FEATURE01');
// Mock with metadata (simulating Relay responses)
Client.assume('FEATURE01')
.false()
.withMetadata({ message: 'Feature disabled for maintenance' });
const response = await switcher.detail().isItOn('FEATURE01') as SwitcherResult;
console.log(response.result); // false
console.log(response.metadata.message); // 'Feature disabled for maintenance'
// Conditional mocking based on input
Client.assume('FEATURE01').true().when(StrategiesType.VALUE, 'premium_user');
console.log(switcher.checkValue('premium_user').isItOn('FEATURE01')); // true
console.log(switcher.checkValue('basic_user').isItOn('FEATURE01')); // false
// Mock with multiple values
Client.assume('FEATURE01').true().when(StrategiesType.NETWORK, ['192.168.1.1', '10.0.0.1']);Enable test mode to prevent file locking during automated testing:
// In your test setup
Client.testMode();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);
}Snapshots enable zero-latency local mode by caching your feature flag configuration.
// Load snapshot from API
const version = await Client.loadSnapshot();
console.log('Loaded snapshot version:', version);Client.watchSnapshot({
success: () => console.log('✅ Snapshot updated successfully'),
reject: (err: Error) => console.error('❌ Snapshot update failed:', err)
});Client.buildContext({ domain, component, environment }, {
local: true,
snapshotLocation: './snapshot/',
snapshotWatcher: true // Enable automatic monitoring
});Verify snapshot currency for external management:
const isLatest = Client.checkSnapshot();
console.log('Snapshot is up to date:', isLatest);Schedule periodic updates for local mode with automatic refresh:
// Update every 3 seconds (3000 milliseconds)
Client.scheduleSnapshotAutoUpdate(3000, {
success: (updated) => console.log('Snapshot updated', updated),
reject: (err: Error) => console.log(err)
});