Node.js Pure JavaScript ZooKeeper Client
node-zookeeper-client is a pure JavaScript client for Apache ZooKeeper, designed to mirror the ZooKeeper Java client API while adhering to Node.js conventions. It provides core functionalities like connecting, creating/removing nodes, retrieving/setting data, and managing ACLs. The current stable version is 1.1.3, last published over four years ago, indicating it is no longer actively maintained. This client has been tested against ZooKeeper version 3.4.*. Unlike some alternatives that wrap the C client, this package is entirely JavaScript-based. Its release cadence is effectively non-existent due to its abandoned status, and it primarily supports callback-based asynchronous operations.
Common errors
-
Failed to create node: %s due to: %s. (KeeperErrorCode = NodeExists)
cause Attempting to create a znode at a path where a node already exists.fixBefore creating a node, use `client.exists(path, callback)` to check if it already exists. Handle the `NODE_EXISTS` exception explicitly if creating an existing node is an expected scenario. -
ZooKeeper client encountered an error: Error: Connection refused
cause The client could not establish a connection to the specified ZooKeeper server. This often indicates the server is not running, is on a different host/port, or a firewall is blocking the connection.fixVerify that the ZooKeeper server process is running and accessible from the Node.js application's host and port. Check firewall rules and the `connectionString` passed to `createClient`. -
WARN Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException: Connection refused
cause Similar to 'Connection refused', this warning (often seen in ZK logs or client output) indicates the client lost connection to the server or couldn't initially connect, often due to network issues, incorrect host/port, or the server being down.fixEnsure the ZooKeeper ensemble is healthy and accessible. Review network configuration and verify the `connectionString`. Also, check ZooKeeper server logs for issues on the server side. -
The lib will segfault if you try to use a ZooKeeper instance after the on_closed event is delivered (possibly as a result of session timeout etc.) YOU MAY NOT re-use the closed ZooKeeper instance.
cause Attempting to perform operations on a `Client` instance after its session has expired or the connection has been explicitly closed, leading to undefined behavior or crashes.fixUpon receiving a 'disconnected' or 'close' event, dispose of the current `Client` instance. If a new connection is needed, create an entirely new client instance using `zookeeper.createClient()`.
Warnings
- breaking This package (node-zookeeper-client by alexguan) is effectively abandoned, with the last publish over four years ago. It only supports ZooKeeper server versions up to 3.4.*, which is severely outdated. For modern ZooKeeper versions (3.5.x+) and active development, consider the `zookeeper` package (yfinkelstein/node-zookeeper) which uses the C client bindings.
- breaking Older versions of this package (1.0.0, 1.1.0, 1.1.1) have known 'severe vulnerabilities exploited'. While the latest 1.1.3 might implicitly fix some, the lack of active maintenance means new vulnerabilities are unlikely to be addressed. It's not recommended for production use due to security risks.
- gotcha This client primarily uses callback-based asynchronous patterns, typical for older Node.js modules. It does not natively support Promises or async/await syntax, which can lead to callback hell in complex applications.
- gotcha The client handles ZooKeeper connection state changes and watcher events through an event emitter API. Developers must explicitly listen for the 'connected', 'disconnected', and 'error' events to manage the client lifecycle and react to network issues or session expirations.
Install
-
npm install node-zookeeper-client -
yarn add node-zookeeper-client -
pnpm add node-zookeeper-client
Imports
- createClient
const createClient = require('node-zookeeper-client').createClient;import { createClient } from 'node-zookeeper-client'; - zookeeper
import zookeeper from 'node-zookeeper-client';
const zookeeper = require('node-zookeeper-client'); - Event
import { Event } from 'node-zookeeper-client';const { Event } = require('node-zookeeper-client'); // or const zookeeper = require('node-zookeeper-client'); const Event = zookeeper.Event;
Quickstart
const zookeeper = require('node-zookeeper-client');
const client = zookeeper.createClient('localhost:2181');
const path = '/my-test-node'; // Using a fixed path for a runnable example
const data = Buffer.from('Hello ZooKeeper');
client.once('connected', function () {
console.log('Connected to the ZooKeeper server.');
client.create(path, data, zookeeper.ACL.OPEN_ACL_UNSAFE, zookeeper.CreateMode.EPHEMERAL, function (error) {
if (error) {
if (error.getCode() === zookeeper.Exception.NODE_EXISTS) {
console.log('Node %s already exists, skipping creation.', path);
} else {
console.error('Failed to create node: %s due to: %s.', path, error);
client.close();
return;
}
} else {
console.log('Node: %s is successfully created with data: %s.', path, data.toString());
}
// Example of getting data
client.getData(path, function (event) {
console.log('Watcher triggered for %s: %s', path, event);
}, function (error, data, stat) {
if (error) {
console.error('Failed to get data from %s due to: %s.', path, error);
} else {
console.log('Data of %s is: %s (version: %d).', path, data.toString(), stat.version);
}
client.close();
});
});
});
client.on('error', function (error) {
console.error('ZooKeeper client encountered an error: %s', error.stack);
});
client.connect();