toggleai-sdk
ToggleAI TypeScript SDK — Universal Feature Flags & Remote Config
The official, universal TypeScript/JavaScript SDK for ToggleAI. Manage feature flags, dynamic remote configurations, progressive canary rollouts, and real-time A/B testing experiments across Node.js, browsers, NestJS, and serverless edge runtimes (Cloudflare Workers, Vercel Edge, Deno, etc.).
Quick Links
Key Features
- Universal Compatibility: Works out of the box in browsers, Node.js 18+, NestJS, and Edge runtimes using isomorphic
fetch. - Zero-Latency Evaluation: Flags are evaluated locally in-memory using math bucketing (sub-millisecond evaluation) to prevent network overhead.
- Real-Time Background Polling: Automated background config updates at customizable intervals.
- Advanced User Targeting: Complete support for percentage rollouts, user attribute segmentation, and targeting rules.
- Progressive Delivery & Canaries: Ingest health metrics and error logs during active pipeline stages for automated rollbacks.
- A/B Testing Experiments: Track variations, record user exposures, and fire conversion metrics.
- Batched Logging: Built-in batched, buffered structured logging with optional global unhandled error capturing.
- Fully Type-Safe: Native TypeScript with support for generics when retrieving configuration variables.
- NestJS Integration: Ready-to-go
ToggleAIModulesupporting synchronous and asynchronous configuration.
Installation
Install the package via your preferred package manager:
npm install toggleai-sdk
# or
yarn add toggleai-sdk
# or
pnpm add toggleai-sdk
Quick Start
1. Initialize the Client
Initialize the ToggleAIClient with your project's client keys. The client automatically reads the backend API URL from the environment (defaulting to the production gateway https://toggleai.bindx.fun).
import { ToggleAIClient } from "toggleai-sdk";
const client = new ToggleAIClient({
clientId: "pk_live_xxxxxxxxxxxxxxxx", // Public Client ID
secret: "sk_live_xxxxxxxxxxxxxxxx", // Private Secret Key
pollingInterval: 30000, // Poll for updates every 30s (default)
});
// Fetch configuration payload and begin background polling
await client.init();
Note on base URLs: The SDK communicates with the official gateway. You can change this gateway globally by setting the
TOGGLEAI_API_URLorVITE_TOGGLEAI_API_URLenvironment variables.
2. Evaluate Feature Flags
Evaluate flags locally from the cached config payload. This uses targeting rules and user attributes without making any network requests.
const context = {
userId: "user_42",
attributes: {
plan: "premium",
country: "US",
},
};
// Boolean flag check
if (client.getFlag("new-billing-flow", context)) {
showNewBillingUI();
}
// Typed variations (string, number, JSON)
const themeColor = client.getFlagValue<string>("hero-button-color", context, "#000000");
const maxUploadLimit = client.getFlagValue<number>("max-upload-mb", context, 20);
3. Read Remote Configs
Dynamic application parameters (configs) are key-value pairs that do not require a user context.
const apiTimeout = client.getConfig<number>("api_timeout_ms", 5000);
const configObject = client.getConfig<{ theme: string }>("ui_styles");
Progressive Delivery & Canaries
ToggleAI supports staged feature rollouts (e.g. 10% → 50% → 100%). During these stages, you can report health metrics and error logs to determine if the rollout is healthy.
1. Sending Health Metrics
Report custom health metrics (like p95 latency, crash rate, or conversion drop-offs) associated with an active pipeline execution stage:
await client.ingestPipelineHealthMetric("ex_canary_checkout_123", {
metricName: "error_rate",
value: 12.5, // If this exceeds the stage's threshold (e.g. 10), the backend auto-rolls back
});
2. Ingesting Execution Error Logs
Send component logs or error boundary events directly to the pipeline telemetry:
try {
runNewCode();
} catch (err) {
await client.ingestPipelineExecutionLogs("ex_canary_checkout_123", {
message: err.message,
level: "error",
stackTrace: err.stack,
});
}
A/B Testing & Experiments
Set up experiments to record user conversions and track user exposure to variations.
1. Auto-Exposure
The SDK automatically registers user exposures in the background when evaluating a flag linked to an active experiment:
// Triggers exposure event under the hood
const result = client.evaluateFlag("hero-cta-experiment", { userId: "user_42" });
2. Attribution Track Event
await client.track({
metricKey: "purchase_completed",
userIdentifier: "user_42",
value: 49.99, // Optional revenue value
});
Logging & Error Monitoring
The SDK includes ToggleAILogger for edge-native logging and error capture. It automatically batches events and flushes them to the backend in the background to minimize overhead.
1. Initializing the Logger
You can retrieve a pre-configured logger attached to your existing ToggleAIClient or create a standalone logger:
// Option A: Get the pre-configured logger from the client
const logger = client.getLogger();
// Option B: Create a standalone logger instance
import { ToggleAILogger } from "toggleai-sdk";
const logger = new ToggleAILogger({
clientId: "pk_live_xxx",
secret: "sk_live_xxx",
minLevel: "info", // Only send logs at or above "info" (default: "debug")
batchSize: 10, // Flush after 10 events (default: 5)
flushInterval: 5000, // Auto-flush timer in ms (default: 5000, set to 0 to disable)
captureGlobalErrors: true, // Auto-capture global uncaught exceptions and unhandled rejections
tags: ["production", "v2.5.0"],
});
2. Log Levels & Structured Context
The logger supports structured context and automatically extracts stacks from Error instances:
// Basic log messages
logger.debug("Parsing request payload", { requestId: "req_123" });
logger.info("Server started successfully");
logger.warn("High database query latency detected");
// Errors can be logged directly (stack traces are automatically extracted)
logger.error(new Error("Database connection failed"));
logger.fatal("System out of memory error");
// Caught error convenience method: captureError
try {
await riskyAction();
} catch (err) {
logger.captureError(err as Error, { userId: "user_42", action: "checkout" });
}
3. Dynamic Context Management
Add or remove persistent context details attached to all subsequent logs:
// Set client-wide context (e.g. after a user logs in)
logger.setContext({ userId: "user_42", tier: "enterprise" });
// Remove a specific key from the context
logger.clearContext("tier");
4. Safe Lifecycle Management
Logs are queued in memory and batched to prevent blocking operations. Always flush or close the logger on process exit to avoid losing pending log events:
// Manually trigger a flush of queued logs
await logger.flush();
// Flush all remaining events and stop the logger
await logger.close();
NestJS Integration
Inject the SDK module directly into your NestJS modules at toggleai-sdk/nestjs.
import { Module } from "@nestjs/common";
import { ToggleAIModule } from "toggleai-sdk/nestjs";
@Module({
imports: [
ToggleAIModule.forRoot({
clientId: "pk_live_xxx",
secret: "sk_live_xxx",
}),
],
})
export class AppModule {}
CI Code Scanner CLI
The ToggleAI SDK ships with a built-in Command Line Interface (CLI) to scan your codebase recursively for active feature flags. It finds references, uploads line numbers & code snippets to the dashboard (enabling flag usage visibility), and warns you if flags enabled in your targeting environment are missing/dead in your code.
Usage
Run the scanner using npx:
npx toggleai scan --project=<project-name> --api-key=<clientId:secret> [options]
Options
| Option | Environment Variable | Description |
|---|---|---|
--project=<name> |
- | The name or ID of the ToggleAI project to scan |
--api-key=<key> |
TOGGLEAI_API_KEY |
Auth keys in "clientId:secret" format |
--client-id=<id> |
TOGGLEAI_CLIENT_ID |
Discrete Client ID |
--secret=<secret> |
TOGGLEAI_SECRET |
Discrete Client Secret |
--dir=<path> |
- | Directory to scan recursively (default: ./src) |
--exclude=<paths> |
- | Comma-separated paths to ignore during scan (e.g. tests,dist,public) |
--env=<env_slug> |
- | Targeting environment to check for active flags (default: production) |
-h, --help |
- | Display help details |
Examples
# Basic scan pointing to standard src folder
npx toggleai scan --project=my-app --api-key=pk_live_xxx:sk_live_xxx
# Custom scan excluding tests and build artifacts
npx toggleai scan --project=my-app --api-key=pk_live_xxx:sk_live_xxx --dir=./lib --exclude=tests,build
API Reference
Client Methods
| Method | Returns | Description |
|---|---|---|
init() |
Promise<void> |
Initialize the client, retrieve configuration, and start background polling |
close() |
void |
Stop polling, flush metrics, and release resources |
refresh() |
Promise<void> |
Manually trigger a remote configuration payload update |
isReady() |
boolean |
Check if configuration is currently cached and ready for evaluation |
getLogger() |
ToggleAILogger |
Get the client's attached logger instance |
Feature Flags
| Method | Returns | Description |
|---|---|---|
getFlag(key, ctx?, default?) |
boolean |
Get boolean flag value locally |
getFlagValue<T>(key, ctx?, default?) |
T |
Get typed flag value locally |
evaluateFlag(key, ctx?) |
FlagEvaluationResult |
Get full local evaluation details (reason, variation) |
evaluateFlagRemote(key, ctx?) |
Promise<FlagEvaluationResult> |
Evaluate flag server-side in real-time |
Progressive Delivery Telemetry
| Method | Returns | Description |
|---|---|---|
ingestPipelineHealthMetric(execId, opts) |
Promise<{ ok: boolean }> |
Ingest a health metric value for a progressive delivery execution |
ingestPipelineExecutionLogs(execId, opts) |
Promise<{ ok: boolean }> |
Ingest log/error telemetry for a progressive delivery execution |
Logging
| Method | Returns | Description |
|---|---|---|
logger.debug(msg, ctx?) |
void |
Queue a debug log event |
logger.info(msg, ctx?) |
void |
Queue an info log event |
logger.warn(msgOrErr, ctx?) |
void |
Queue a warning log event (extracts Error stack if applicable) |
logger.error(msgOrErr, ctx?) |
void |
Queue an error log event (extracts Error stack if applicable) |
logger.fatal(msgOrErr, ctx?) |
void |
Queue a fatal log event (extracts Error stack if applicable) |
logger.captureError(err, ctx?) |
void |
Queue an error event with errorClass metadata |
logger.setContext(ctx) |
void |
Set persistent default context fields |
logger.clearContext(key) |
void |
Clear a persistent default context field |
logger.flush() |
Promise<void> |
Force manual flush of queued log events to the backend |
logger.close() |
Promise<void> |
Stop background timers, flush remaining queue, and shut down logger |
Backend Endpoints
The SDK communicates with the following public endpoints under the /sdk route (authenticated via API keys):
| Endpoint | Method | Description |
|---|---|---|
/sdk/config |
GET |
Fetch the full configuration payload (flags + configs) |
/sdk/evaluate |
POST |
Server-side evaluate all flags for a given context |
/sdk/evaluate/:flagKey |
POST |
Server-side evaluate a single flag for a context |
/sdk/connect |
POST |
Register SDK connection status |
/sdk/metrics |
POST |
Batch report evaluation counts and cache hit rates |
/sdk/executions/:executionId/health-metric |
POST |
Ingest health metric for progressive delivery pipeline validation |
/sdk/executions/:executionId/logs |
POST |
Ingest execution error logs during progressive stages |
Frequently Asked Questions (FAQ)
How does ToggleAI achieve sub-millisecond evaluation latency?
The SDK operates in local evaluation mode by default. During client.init(), the SDK calls /sdk/config to download the entire configuration manifest. All subsequent evaluations (client.getFlag(), etc.) are computed in-memory locally using mathematical user-ID hashing and conditional rule matching, requiring zero network round-trips.
What happens if the ToggleAI API goes down?
The SDK is designed to fail gracefully. If the configuration payload cannot be fetched on startup or during a poll cycle, the SDK falls back to the default values provided in your code. Network failures do not block thread execution or impact user experience.
Can I use the SDK in serverless or edge environments?
Yes. The SDK is built with universal modules and uses standard fetch APIs instead of platform-specific libraries. It runs efficiently in Vercel Edge functions, Cloudflare Workers, AWS Lambda, Node.js, and directly in client browsers.
Support
For questions, bug reports, or feature requests, contact support via our Documentation Portal or submit an issue on the GitHub repository.