{"id":11962,"library":"rox-node","title":"CloudBees Feature Management Node.js SDK","description":"The `rox-node` package is the Node.js SDK for CloudBees Feature Management (formerly Rollout.io), offering capabilities for defining and managing feature flags, remote configuration variables, and custom properties within Node.js applications. Currently stable at version 6.0.8, this SDK enables developers to control application features dynamically via the CloudBees Feature Management dashboard, facilitating controlled rollouts, A/B testing, and targeted user experiences. It is designed for enterprise-grade feature management, providing secure and scalable solutions for accelerating development and minimizing deployment risk. The package is updated regularly, with its latest version published approximately four months ago as of late 2025. Key differentiators include its focus on secure feature management, advanced target grouping, and integration with the CloudBees ecosystem, which caters to complex production environments by allowing dynamic control over features without requiring code redeployments.","status":"active","version":"6.0.8","language":"javascript","source_language":"en","source_url":"https://github.com/rollout/roxjs","tags":["javascript","feature-flag","feature-flags","rollout","rox","flags","flag","configuration","remote-control"],"install":[{"cmd":"npm install rox-node","lang":"bash","label":"npm"},{"cmd":"yarn add rox-node","lang":"bash","label":"yarn"},{"cmd":"pnpm add rox-node","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary import for the SDK. While `require` works for CommonJS, modern Node.js applications often use ES Modules (`import`). For TypeScript projects, `import Rox from 'rox-node';` is the standard, requiring `@types/rox-node` for type safety.","wrong":"const Rox = require('rox-node');","symbol":"Rox","correct":"import Rox from 'rox-node';"},{"note":"`Flag` is a class nested under the `Rox` object, used to define boolean feature flags. It's not a named export from the `rox-node` module directly. Other types like `Rox.RoxString` and `Rox.RoxNumber` follow the same pattern.","wrong":"import { Flag } from 'rox-node'; const flags = { newFeature: new Flag(false) };","symbol":"Rox.Flag","correct":"const flags = { newFeature: new Rox.Flag(false) };"},{"note":"Used to initialize the SDK with your application's SDK key. This is an asynchronous operation and should typically be `await`ed. The SDK key should be sourced from environment variables, not hardcoded.","wrong":"Rox.setup('<YOUR_SDK_KEY>', options);","symbol":"Rox.setup","correct":"await Rox.setup(process.env.ROX_SDK_KEY ?? '', options);"}],"quickstart":{"code":"import Rox from 'rox-node';\n\n// Define your feature flags in a container object\nconst flags = {\n  enableBetaFeature: new Rox.Flag(false), // Default value is false\n  welcomeMessage: new Rox.RoxString('Hello, User!', ['Welcome!', 'Greetings!', 'Hello, User!']),\n  discountPercentage: new Rox.RoxNumber(0, [0, 5, 10, 15])\n};\n\nasync function initializeFeatureManagement() {\n  const SDK_KEY = process.env.ROX_SDK_KEY ?? 'YOUR_DEFAULT_SDK_KEY'; // Securely get your SDK key\n\n  if (SDK_KEY === 'YOUR_DEFAULT_SDK_KEY') {\n    console.warn('WARNING: ROX_SDK_KEY environment variable not set. Using a default key which may not connect to your dashboard.');\n  }\n\n  // Register the flags with an optional namespace (empty string for global namespace)\n  Rox.register('', flags);\n\n  try {\n    // Initialize the SDK - this connects to the CloudBees Feature Management server\n    await Rox.setup(SDK_KEY, { /* Optional Rox options */ });\n    console.log('CloudBees Feature Management SDK initialized successfully.');\n\n    // Evaluate flags after initialization\n    if (flags.enableBetaFeature.isEnabled()) {\n      console.log('Beta feature is ENABLED!');\n      // Logic for beta feature\n    } else {\n      console.log('Beta feature is DISABLED.');\n    }\n\n    console.log(`Welcome message: ${flags.welcomeMessage.getValue()}`);\n    console.log(`Discount: ${flags.discountPercentage.getValue()}%`);\n\n  } catch (error) {\n    console.error('Failed to initialize CloudBees Feature Management SDK:', error);\n    // Fallback logic if SDK fails to initialize\n    console.log('Using local default values for flags.');\n  }\n}\n\ninitializeFeatureManagement();","lang":"typescript","description":"Demonstrates the asynchronous initialization of the `rox-node` SDK, registration of feature flags (boolean, string, and number types), and evaluation of these flags after setup. It emphasizes using environment variables for the SDK key and includes basic error handling."},"warnings":[{"fix":"Ensure all `Rox.Flag`, `Rox.RoxString`, and `Rox.RoxNumber` constructors are passed a sensible default value that dictates application behavior in the absence of remote configuration.","message":"Always provide a robust default value when defining flags (e.g., `new Rox.Flag(false)`). If the SDK fails to connect or a flag is not configured in the dashboard, the default value ensures predictable application behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Run `npm i @types/rox-node --save-dev` to install the necessary TypeScript declaration files.","message":"For TypeScript projects, you must install the type definitions package `@types/rox-node` separately. Without it, you will encounter TypeScript compilation errors related to unknown types or modules.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always call `Rox.setup` using `await` within an `async` function, or chain `.then()` and `.catch()` to handle the promise. Ensure flag evaluation logic runs only after `Rox.setup` resolves.","message":"The `Rox.setup` method is asynchronous. It's crucial to `await` its completion or handle its promise to ensure flags are loaded before attempting to evaluate them. Evaluating flags before the SDK is ready may result in incorrect or default values.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Store your SDK key securely in environment variables (e.g., `process.env.ROX_SDK_KEY`) and inject it into your application at runtime. Avoid committing sensitive keys to version control.","message":"The SDK key should never be hardcoded or exposed in client-side code, especially in production environments. Exposure can lead to unauthorized access and manipulation of your feature flags.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Wrap `Rox.setup` in a `try-catch` block and consider implementing a timeout or retry mechanism. Ensure your application can function correctly with default flag values if network access to the feature management service is unavailable.","message":"The SDK relies on network connectivity to fetch flag configurations. In environments with unstable networks, slow initialization might occur. Implement robust error handling around `Rox.setup` to manage network failures gracefully.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Run `npm install rox-node` or `yarn add rox-node` to install the package. Ensure your environment's `NODE_PATH` is correctly configured if not using standard `node_modules` resolution.","cause":"The `rox-node` package is not installed or incorrectly resolved by Node.js module resolution.","error":"Error: Cannot find module 'rox-node'"},{"fix":"Verify `import Rox from 'rox-node';` is at the top of your file. Ensure that `Rox.setup` has been called and `await`ed before `new Rox.Flag()` is invoked.","cause":"The `Rox` object (or the `Flag` class) was not properly imported or initialized before use. This often happens if `import Rox from 'rox-node'` is missing or if `Rox.setup` hasn't completed.","error":"TypeError: Rox.Flag is not a constructor"},{"fix":"Ensure that your `flags` object is correctly defined and `Rox.register('', flags)` has been executed before attempting to access `flags.myFlag.isEnabled()` or `flags.myString.getValue()`. Additionally, ensure `Rox.setup` has finished.","cause":"This error typically occurs when a `Rox.Flag` instance (or `Rox.RoxString`, `Rox.RoxNumber`) is accessed before it has been properly defined within the `flags` object and `Rox.register` has been called.","error":"TypeError: Cannot read properties of undefined (reading 'isEnabled')"},{"fix":"For serverless functions (e.g., AWS Lambda, Vercel), ensure `rox-node` is included in your deployment package. Check build steps to confirm `node_modules` are correctly packaged. Verify `rox-node` is listed in your `dependencies` in `package.json` for production deployments.","cause":"This is a serverless or bundled environment specific variation of 'Cannot find module', indicating that the module was not included in the deployment package or the runtime environment cannot locate it.","error":"Runtime.ImportModuleError: Error: Cannot find module 'rox-node'"}],"ecosystem":"npm"}