VWO Feature Management and Experimentation SDK

raw JSON →
1.41.0 verified Thu Apr 23 auth: no javascript

The VWO Feature Management and Experimentation SDK (vwo-fme-node-sdk) provides robust capabilities for integrating feature flagging and experimentation directly into Node.js and browser-based JavaScript applications. Currently stable at version 1.41.0, the library receives consistent updates, indicated by frequent minor and patch releases. It allows developers to dynamically manage feature rollouts, conduct A/B tests, and track user interaction events within the VWO platform. Key features include the ability to specify custom bucketing seeds for consistent user group assignments (v1.41.0), automatic session management (v1.37.0) to link server-side decisions with client-side experiences, and a flexible `Connector` API (v1.35.0) for custom persistent storage of VWO settings. Notably, a significant architectural change in v1.36.0 shifted the SDK from a singleton model to supporting multiple isolated instances, enhancing flexibility for complex application architectures.

error TypeError: (0, _vwoFmeNodeSdk.init) is not a function
cause Attempting to destructure `init` from a CommonJS `require()` call when the SDK is primarily an ES module or when using an older Node.js version that treats `.js` files as CommonJS by default, while the SDK expects ES module imports.
fix
If using Node.js with ES modules ("type": "module" in package.json or .mjs files), use import { init } from 'vwo-fme-node-sdk';. If strictly using CommonJS, ensure your environment correctly handles the module interoperability or use a bundler that transpiles correctly. Often, switching to ESM imports is the most straightforward fix.
error UnhandledPromiseRejectionWarning: VWOClientError: SDK not initialized. Call init() first.
cause The SDK client (`vwoClient`) was used before the asynchronous `init()` function completed, or `init()` failed to resolve.
fix
Always await the init() call to ensure the VWO client is fully initialized before attempting to use any of its methods like getFlag or trackEvent. Wrap SDK usage in an async function.
error TypeError: Cannot read properties of undefined (reading 'isEnabled')
cause This typically occurs when `vwoClient.getFlag()` returns `undefined` (e.g., due to an invalid flag key, network issue, or client not being fully initialized), and you attempt to call a method like `isEnabled()` on it.
fix
Always check if the Flag object returned by getFlag() is valid before accessing its properties or methods, e.g., if (feature && feature.isEnabled()) { ... }. Ensure your sdkKey and flagKey are correct and the client is properly initialized.
gotcha The `shutdown()` API was introduced in v1.42.0 to support graceful teardown in long-running environments. Failing to call `shutdown()` can lead to resource leaks and prevent batched events from being flushed, especially in serverless or containerized setups where processes terminate without explicit cleanup.
fix Ensure `vwoClient.shutdown()` is called before your application process exits or when the client is no longer needed. For example, in a server, call it during the server's graceful shutdown hook.
breaking In v1.36.0, the SDK refactored from a singleton pattern to support multiple isolated instances. If your application implicitly relied on shared state across what you considered separate client initializations (which previously all pointed to the same singleton), their behavior will change. Each `init()` call now creates a truly independent client instance with its own state and utilities.
fix Review any code that might have depended on shared state across `vwoClient` instances. Ensure each instance is managed and configured independently. If global access is still desired, manually manage a single instance or pass it explicitly.
gotcha Version 1.41.0 introduced support for `bucketingSeed` in the context object. This allows users to be bucketed by a shared identifier (e.g., `companyId`) instead of the individual `userId`, ensuring all users within the same group receive the same variation. Without this, bucketing is strictly per individual user ID.
fix To enable group-based bucketing, include `bucketingSeed: 'your-group-id'` in your user context object when calling `getFlag` or `trackEvent`.
gotcha Since v1.38.0, the SDK allows using the context `id` directly as the visitor UUID instead of generating a new one. This is crucial if you need to maintain a consistent UUID across server-side and client-side interactions, especially when integrating with the VWO web client.
fix When initializing `vwoClient` or in the user context, if you want your `id` to be the UUID, ensure it's a stable identifier. You can retrieve the assigned UUID via `flag.getUUID()` to pass to other clients.
gotcha V1.35.0 introduced the `Connector` class for enabling persistent storage and retrieval of VWO settings via custom storage connectors. If you need to cache settings or visitor data between application restarts or across different instances, you must implement and provide a custom `Connector`.
fix Extend the `StorageConnector` class and implement `getSettings`, `setSettings`, `get`, and `set` methods. Pass an instance of your custom connector to the `init()` options: `{ storage: new MyCustomStorageConnector() }`.
npm install vwo-fme-node-sdk
yarn add vwo-fme-node-sdk
pnpm add vwo-fme-node-sdk

Demonstrates initializing the VWO client, evaluating a feature flag, retrieving a variable, tracking an event, and gracefully shutting down the client in a TypeScript environment.

import { init, IVWOClient, IVWOOptions, Flag } from 'vwo-fme-node-sdk';

(async () => {
  const options: IVWOOptions = {
    accountId: process.env.VWO_ACCOUNT_ID ?? '123456',
    sdkKey: process.env.VWO_SDK_KEY ?? '32-alpha-numeric-sdk-key'
  };

  const vwoClient: IVWOClient = await init(options);

  const userContext = { id: 'unique_user_id', customData: { role: 'admin' } };
  const feature: Flag = await vwoClient.getFlag('premium_feature', userContext);

  if (feature.isEnabled()) {
    console.log('Premium feature is enabled for the user!');
    const discountLevel: number = feature.getVariable('discount_level', 0);
    console.log(`User receives a ${discountLevel}% discount.`);
  } else {
    console.log('Premium feature is not enabled.');
  }

  // Track an event after a feature decision or user action
  vwoClient.trackEvent('premium_feature_used', userContext);

  // Gracefully shut down the client in long-running processes (Node.js servers)
  vwoClient.shutdown();
})();