A lightweight, real-time feature flag SDK for JavaScript applications. Zero dependencies, full TypeScript support, and works in both browser and Node.js environments.
- 🚀 Real-time Updates - Instant flag changes via Server-Sent Events
- 📦 Tiny Bundle - Only 7.4 KB gzipped (2.8x smaller than LaunchDarkly)
- 💾 Smart Caching - Works offline with local storage support
- 🔒 Type Safe - Full TypeScript definitions included
- 🌐 Universal - Browser and Node.js support
- ♻️ Auto-reconnection - Resilient connection handling
npm install @togglecraft/js-sdk
# or
yarn add @togglecraft/js-sdkimport { ToggleCraftClient } from '@togglecraft/js-sdk';
// Initialize client
const client = new ToggleCraftClient({
sdkKey: 'your-sdk-key'
});
// Connect and wait for flags
await client.connect();
await client.waitForReady();
// Use your flags
if (client.isEnabled('new-feature', { user: currentUser })) {
// Feature is enabled
}import { ToggleCraftClient } from '@togglecraft/js-sdk';
const client = new ToggleCraftClient({
sdkKey: 'your-sdk-key',
cacheAdapter: 'memory' // Use memory cache in Node.js
});
await client.connect();
if (client.isEnabled('feature-flag', context)) {
// Feature enabled logic
}Note: Node.js requires the eventsource package for SSE support:
npm install eventsourceSimple on/off feature toggles:
if (client.isEnabled('dark-mode', { user: { id: '123' } })) {
enableDarkMode();
}A/B/n testing with multiple variants:
const variant = client.getVariant('checkout-flow', { user: { id: '123' } });
switch (variant) {
case 'one-page':
renderOnePageCheckout();
break;
case 'multi-step':
renderMultiStepCheckout();
break;
default:
renderDefaultCheckout();
}Gradual feature rollouts:
if (client.isInPercentage('new-algorithm', { user: { id: '123' } })) {
useNewAlgorithm();
} else {
useLegacyAlgorithm();
}const client = new ToggleCraftClient({
// Required
sdkKey: 'your-sdk-key', // Get from ToggleCraft dashboard
// Optional - Common settings
enableCache: true, // Enable caching (default: true)
cacheAdapter: 'localStorage', // 'memory' or 'localStorage' (default: 'memory')
cacheTTL: 300000, // Cache TTL in ms (default: 5 minutes)
debug: false // Enable debug logging (default: false)
});Need more control? See Advanced Configuration →
The context object provides data for targeting rules:
const context = {
user: {
id: 'user-123', // Required for consistent evaluation
email: 'user@example.com',
plan: 'premium',
// Add any custom attributes you need
role: 'admin',
company_id: 'acme-corp'
},
request: {
ip: '192.168.1.1',
country: 'US'
},
device: {
type: 'mobile',
os: 'iOS'
}
};
client.isEnabled('premium-feature', context);You can add any custom properties - the SDK evaluates all attributes using dot notation (e.g., user.role, request.country).
# Download hooks from GitHub (examples not included in npm package)
curl -o src/hooks/useToggleCraft.js https://raw.githubusercontent.com/togglecraft/js-sdk/main/examples/frameworks/react/useToggleCraft.jsimport { useFeatureFlag } from './hooks/useToggleCraft';
function MyComponent() {
const { enabled, isReady } = useFeatureFlag('new-feature', {
user: { id: currentUser.id }
});
if (!isReady) return <Loading />;
return enabled ? <NewFeature /> : <OldFeature />;
}Full React Integration Guide →
# Download composables from GitHub (examples not included in npm package)
curl -o src/composables/useToggleCraft.js https://raw.githubusercontent.com/togglecraft/js-sdk/main/examples/frameworks/vue/useToggleCraft.js<script setup>
import { useFeatureFlag } from '@/composables/useToggleCraft';
const { enabled, isReady } = useFeatureFlag('new-feature', {
user: { id: '123' }
});
</script>
<template>
<NewFeature v-if="enabled" />
<OldFeature v-else />
</template>Full Vue 3 Integration Guide →
Listen for real-time updates:
// Flags are ready
client.on('ready', () => {
console.log('Client ready!');
});
// Flags updated in real-time
client.on('flagsUpdated', (flags) => {
console.log('Flags updated:', Object.keys(flags));
});
// Connection lost
client.on('disconnected', () => {
console.log('Disconnected - using cached flags');
});
// Error occurred
client.on('error', (error) => {
console.error('Error:', error);
});Always provide default values and handle errors gracefully:
// Safe evaluation with defaults
const isEnabled = client.isEnabled('feature', context, false);
// Returns false if flag doesn't exist or on error
// Handle connection errors
try {
await client.connect();
} catch (error) {
console.error('Failed to connect:', error);
// App still works with cached values or defaults
}- Initialize Once - Create a single client instance and reuse it
- Always Provide Context - Include at least
user.idfor consistent evaluation - Use Default Values - Handle missing flags gracefully
- Clean Up on Shutdown - Call
client.destroy()when closing
// On application shutdown
process.on('SIGTERM', () => {
client.destroy();
});Core Methods:
isEnabled(flagKey, context?, defaultValue?)- Check boolean flagsgetVariant(flagKey, context?, defaultVariant?)- Get multivariate variantisInPercentage(flagKey, context?, defaultValue?)- Check percentage rollout
Connection:
connect()- Connect to SSE serverdisconnect()- Disconnect from serverisReady()- Check if client has flags loadedwaitForReady(timeout?)- Wait for client to be ready
Power users can customize:
- Connection pooling and reconnection strategies
- Scheduled rollout stages with automatic transitions
- Custom cache adapters
- Hybrid reconnection with exponential backoff
Check out the examples/ directory for:
- browser.html - Complete browser integration with UI
- node-example.js - Node.js server implementation
- frameworks/react/ - Production-ready React hooks
- frameworks/vue/ - Production-ready Vue 3 composables
Client not connecting?
- Verify your SDK key is correct
- Check that you called
initToggleCraft()before using hooks (React/Vue) - Ensure your firewall allows connections to
sse.togglecraft.io
Flags not updating?
- Verify the SSE connection is established (
client.isConnected()) - Check the browser console for error messages
- Enable debug mode:
{ debug: true }
- Node.js 14.0+ (for ES Modules support)
- Modern browsers - Chrome 61+, Firefox 60+, Safari 11+, Edge 79+
- Optional:
eventsourcepackage for Node.js SSE support
Using CommonJS? See Troubleshooting Guide
| Browser | Version |
|---|---|
| Chrome | 61+ |
| Firefox | 60+ |
| Safari | 11+ |
| Edge | 79+ |
For older browsers, you may need polyfills for Promise, EventSource, and Object.entries.
- API Reference - Complete API documentation
- Advanced Features - Connection pooling, rollout stages, custom configuration
- Framework Integration - React and Vue 3 detailed guides
- Troubleshooting - Common issues and solutions
- Security - Security best practices and policies
The SDK is extremely lightweight with zero production dependencies:
| SDK | Gzipped Size | Difference |
|---|---|---|
| ToggleCraft | 7.4 KB | - |
| LaunchDarkly JS Client SDK | 20.7 KB | 2.8x larger |
| Unleash Proxy Client | 6.6 KB | Comparable |
Note: Sizes measured for latest versions (October 2025) using minified + gzipped bundles. Tree-shaking is fully supported - import only what you need!
MIT
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
- Documentation: GitHub Repository
- Issues: GitHub Issues
- Security: See SECURITY.md for reporting vulnerabilities