node-client-sdk
LaunchDarkly's client-side feature-flag SDK for single-user Node.js apps, now superseded by the scoped @launchdarkly/node-client-sdk package.
Repository Health
Technical Analysis
The LaunchDarkly Client-Side SDK for Node.js lets a single-user Node process — a desktop app, CLI tool, or smart-device application — evaluate LaunchDarkly feature flags locally after an initial connection, cache the last-known flag values to disk, and receive live updates over a persistent streaming connection. It follows the same client-side (single-context) model as LaunchDarkly’s browser and Electron SDKs rather than the multi-user model used by server-side SDKs, so it is not meant for web servers handling many concurrent users.
The repository’s README now states the project has been renamed to @launchdarkly/node-client-sdk and moved into LaunchDarkly’s js-core monorepo, with all future releases and issue tracking happening there; this package still receives npm releases under its original name and remains in active use, but new integrations should generally target the renamed package instead.
What You Get
- A single initialize(envKey, context, options) call that returns a ready-to-use LDClient instance
- Real-time flag updates delivered over a managed Server-Sent Events stream
- On-disk local storage (via node-localstorage) that caches anonymous context keys and last-known flag values between runs
- Hand-maintained TypeScript ambient typings (typings.d.ts) for editor and type-check support despite a plain-JS implementation
- A pluggable basicLogger implementation plus a tlsParams option for custom certificates and mutual TLS
Common Use Cases
- Feature-gating desktop and CLI applications tied to a single end user
- Progressive rollouts for IoT and smart-device software with intermittent connectivity
- Secure-mode single-user client integrations that pass a signed context hash
- Bridging existing integrations while a team migrates to the renamed @launchdarkly/node-client-sdk package
Under The Hood
Architecture The package is a deliberately thin platform adapter: src/index.js builds a Node-specific platform object via nodePlatform.js and hands it, along with a couple of extra option definitions (localStoragePath, tlsParams, hash), to launchdarkly-js-sdk-common’s initialize(), which owns all flag-evaluation, event-queueing, and context/identify logic. nodePlatform.js supplies the platform-specific primitives that common code needs — an httpRequest wrapper (httpRequest.js) around Node’s http/https modules, a node-localstorage-backed cache for anonymous keys and last-known flags, an EventSource factory from launchdarkly-eventsource for streaming, and TLS parameter filtering for secure requests. There is essentially no independent application logic here beyond wiring these platform primitives together, so the package’s correctness depends almost entirely on the shared common library staying compatible with this adapter’s platform object shape.
Tech Stack Plain JavaScript (not TypeScript) targeting Node.js >= 12, built and tested with Babel (babel.config.js, @babel/preset-env) and Jest (jest-junit for CI reporting), linted with ESLint using the xo config plus eslint-config-prettier/eslint-plugin-prettier, and documented via TypeDoc against the project’s hand-written typings.d.ts. Runtime dependencies are launchdarkly-js-sdk-common (the shared evaluation/event engine), launchdarkly-eventsource (SSE streaming), and node-localstorage (on-disk cache). CI runs on GitHub Actions across a small Node version matrix and additionally spins up a contract-tests service that LaunchDarkly’s centralized sdk-test-harness drives for cross-SDK conformance testing.
Code Quality Tests live under src/tests and use Jest with launchdarkly-js-test-helpers, which spins up ephemeral local HTTP servers to assert on initialization/ready events, User-Agent headers, track() behavior, streaming, and TLS handling — a reasonably thorough behavioral suite for such a small adapter layer, reinforced by the external LaunchDarkly contract-test harness run in CI. Error handling is mostly a thin pass-through: httpRequest.js rejects its returned promise on any Node HTTP error, while most validation and error surfacing lives in the shared common package rather than this repo. Naming is consistent and idiomatic Node/CommonJS; there is no static typing in the implementation itself (typings.d.ts is a separate hand-maintained ambient declaration file, not derived from the JS source), and CI enforces linting and a TypeScript type-check pass against those typings.
API Design The public surface is intentionally minimal: a single initialize(envKey, context, options) factory returns a client whose readiness is observed via waitForInitialization() or a ‘ready’ event, plus a basicLogger() convenience export for a simple leveled console logger. Nearly every interesting piece of behavior — flag evaluation, identify/context handling, event batching — is inherited unmodified from launchdarkly-js-sdk-common, so a developer already familiar with LaunchDarkly’s browser or Electron client SDKs gets the same API here with almost no relearning. That consistency is a genuine DX win across LaunchDarkly’s client-SDK family, but the API design itself is not something this specific package originates; it is a straightforward implementation of a shape defined elsewhere, and the package’s own npm listing now points integrators toward its renamed successor.