@code-signal/signal
v1.3.0
Published
Feature flag management SDK for modern web applications — server-side evaluation, real-time sync, React bindings, and OpenFeature support.
Maintainers
Readme
@code-signal/signal
Feature flag management SDK for modern web applications.
Ship faster, reduce risk, and control every release — without redeployment.
Features
- Server-side evaluation — local flag evaluation for zero-latency (Node.js / SSR)
- Client-side sync — lightweight browser client with real-time updates via WebSocket
- React bindings — hooks and context provider out of the box
- OpenFeature support — drop-in providers for the OpenFeature standard
- A/B testing — built-in variant management and conversion tracking
- Type-safe flag keys — define flags as typed constants, no magic strings
Installation
npm install @code-signal/signalQuick start
Server-side (Node.js / SSR)
import { initializeServer, getServerInstance } from '@code-signal/signal';
await initializeServer({
apiKey: process.env.SIGNAL_API_KEY,
projectId: process.env.SIGNAL_PROJECT_ID,
apiUrl: process.env.SIGNAL_API_URL,
});
const signal = getServerInstance();
const enabled = await signal.isEnabled('my-feature', { userId: 'user-123' });Client-side (browser)
import { initializeClient, getClientInstance } from '@code-signal/signal';
await initializeClient({
apiKey: process.env.NEXT_PUBLIC_SIGNAL_API_KEY,
projectId: process.env.NEXT_PUBLIC_SIGNAL_PROJECT_ID,
apiUrl: process.env.NEXT_PUBLIC_SIGNAL_API_URL,
websocket: { enabled: true },
});
const signal = getClientInstance();
const enabled = await signal.isEnabled('my-feature');React
import { FeatureFlagsProvider, useFeatureFlag } from '@code-signal/signal';
function App() {
return (
<FeatureFlagsProvider config={{ apiKey: '...', projectId: '...', apiUrl: '...' }}>
<MyComponent />
</FeatureFlagsProvider>
);
}
function MyComponent() {
const { enabled, loading } = useFeatureFlag('my-feature');
if (loading) return null;
return enabled ? <NewUI /> : <OldUI />;
}OpenFeature
import { OpenFeature } from '@openfeature/server-sdk';
import { SignalServerProvider } from '@code-signal/signal';
await OpenFeature.setProviderAndWait(
new SignalServerProvider({
apiKey: process.env.SIGNAL_API_KEY,
projectId: process.env.SIGNAL_PROJECT_ID,
apiUrl: process.env.SIGNAL_API_URL,
})
);
const client = OpenFeature.getClient();
const enabled = await client.getBooleanValue('my-feature', false);Type-safe flag keys
Define your flags once and reference them safely across your codebase:
import { createFeatureFlag } from '@code-signal/signal';
export const FLAGS = {
NEW_CHECKOUT: createFeatureFlag('new-checkout'),
DARK_MODE: createFeatureFlag('dark-mode'),
} as const;
// Usage
const enabled = await signal.isEnabled(FLAGS.NEW_CHECKOUT);Real-time updates
Enable WebSocket sync to receive flag changes instantly without polling:
await initializeClient({
// ...
websocket: { enabled: true },
onUpdate: (flags) => console.log('Flags updated:', flags),
});Configuration
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | required | Your Signal API key (sig_live_...) |
| projectId | string | required | Your Signal project ID |
| apiUrl | string | required | Signal API base URL |
| environment | string | production | Target environment |
| syncInterval | number | 30000 | Polling interval in ms (server) |
| websocket.enabled | boolean | false | Enable real-time WebSocket sync |
| analytics.enabled | boolean | false | Enable analytics tracking |
| abTesting.enabled | boolean | false | Enable A/B testing |
License
MIT
