Skip to content

ToggleCraft/js-sdk

Repository files navigation

ToggleCraft JavaScript SDK

A lightweight, real-time feature flag SDK for JavaScript applications. Zero dependencies, full TypeScript support, and works in both browser and Node.js environments.

Why ToggleCraft?

  • 🚀 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

Installation

npm install @togglecraft/js-sdk

# or

yarn add @togglecraft/js-sdk

Quick Start

Browser

import { 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
}

Node.js

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 eventsource

Basic Usage

Boolean Flags

Simple on/off feature toggles:

if (client.isEnabled('dark-mode', { user: { id: '123' } })) {
  enableDarkMode();
}

Multivariate Flags

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();
}

Percentage Rollouts

Gradual feature rollouts:

if (client.isInPercentage('new-algorithm', { user: { id: '123' } })) {
  useNewAlgorithm();
} else {
  useLegacyAlgorithm();
}

Configuration

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 →

Evaluation Context

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).

Framework Integration

React

# 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.js
import { 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 →

Vue 3

# 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 →

Event Handling

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);
});

Error Handling

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
}

Best Practices

  1. Initialize Once - Create a single client instance and reuse it
  2. Always Provide Context - Include at least user.id for consistent evaluation
  3. Use Default Values - Handle missing flags gracefully
  4. Clean Up on Shutdown - Call client.destroy() when closing
// On application shutdown
process.on('SIGTERM', () => {
  client.destroy();
});

API Reference

Core Methods:

  • isEnabled(flagKey, context?, defaultValue?) - Check boolean flags
  • getVariant(flagKey, context?, defaultVariant?) - Get multivariate variant
  • isInPercentage(flagKey, context?, defaultValue?) - Check percentage rollout

Connection:

  • connect() - Connect to SSE server
  • disconnect() - Disconnect from server
  • isReady() - Check if client has flags loaded
  • waitForReady(timeout?) - Wait for client to be ready

Full API Documentation →

Advanced Features

Power users can customize:

  • Connection pooling and reconnection strategies
  • Scheduled rollout stages with automatic transitions
  • Custom cache adapters
  • Hybrid reconnection with exponential backoff

Advanced Features Guide →

Examples

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

Troubleshooting

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 }

More Troubleshooting →

Requirements

  • Node.js 14.0+ (for ES Modules support)
  • Modern browsers - Chrome 61+, Firefox 60+, Safari 11+, Edge 79+
  • Optional: eventsource package for Node.js SSE support

Using CommonJS? See Troubleshooting Guide

Browser Support

Browser Version
Chrome 61+
Firefox 60+
Safari 11+
Edge 79+

For older browsers, you may need polyfills for Promise, EventSource, and Object.entries.

Documentation

Bundle Size

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!

License

MIT

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

Support

About

No description, website, or topics provided.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published