{"id":15726,"library":"node-nailgun-client","title":"Node.js Nailgun Client","description":"node-nailgun-client provides a Node.js API and command-line interface (CLI) for interacting with a Nailgun server. Nailgun is a system designed to run Java programs from the command line without incurring the typical JVM startup overhead, acting as a long-running JVM server that executes commands sent from a client. This package allows Node.js applications to programmatically execute Java code via the Nailgun protocol. The current and only stable version is 0.1.2, last published over seven years ago. The package's development is abandoned, coinciding with the upstream Nailgun project itself being officially unmaintained since April 2023. Key differentiators included its attempt to integrate high-performance Java execution within Node.js workflows by leveraging Nailgun's persistent JVM model.","status":"abandoned","version":"0.1.2","language":"javascript","source_language":"en","source_url":"https://github.com/markushedvall/node-nailgun-client","tags":["javascript"],"install":[{"cmd":"npm install node-nailgun-client","lang":"bash","label":"npm"},{"cmd":"yarn add node-nailgun-client","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-nailgun-client","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This package is CommonJS only; direct ESM `import` is not supported. The `nailgunClient` object provides the primary API.","wrong":"import nailgunClient from 'node-nailgun-client';","symbol":"nailgunClient","correct":"const nailgunClient = require('node-nailgun-client');"},{"note":"The `exec` function is a method of the `nailgunClient` object, not a named export. It returns a child process-like object for stream interaction.","wrong":"const { exec } = require('node-nailgun-client');","symbol":"exec","correct":"const nail = nailgunClient.exec('command-name', args, options);"}],"quickstart":{"code":"const nailgunClient = require('node-nailgun-client');\n\n// Basic execution of a Nailgun command (e.g., 'ng-stats' for server status)\nconst simpleNail = nailgunClient.exec('ng-stats');\nsimpleNail.stdout.pipe(process.stdout);\nsimpleNail.stderr.pipe(process.stderr);\nsimpleNail.on('exit', (code) => {\n  if (code !== 0) {\n    console.error(`ng-stats exited with code ${code}`);\n  }\n});\n\n// Executing a custom Java class with arguments and explicit server options\nconst options = {\n  address: 'localhost',\n  port: 2113\n};\nconst args = ['hello', 'world'];\n\nconst customNail = nailgunClient.exec('com.example.MyJavaClass', args, options);\n\ncustomNail.stdout.pipe(process.stdout); // Pipe Java's stdout to Node's stdout\ncustomNail.stderr.pipe(process.stderr); // Pipe Java's stderr to Node's stderr\n\n// Optionally pipe Node's stdin to Java's stdin if the Java program expects input\n// process.stdin.pipe(customNail.stdin);\n\ncustomNail.on('exit', (code) => {\n  console.log(`Java program exited with code ${code}`);\n  // process.exit(code); // Uncomment to exit Node.js with the Java program's exit code\n});","lang":"javascript","description":"Demonstrates how to execute a basic Nailgun command and a custom Java class with arguments and server configuration, handling I/O streams and exit codes."},"warnings":[{"fix":"Consider alternative inter-process communication (IPC) methods or FFI for integrating Node.js with Java, or using a more actively maintained Nailgun client if available.","message":"The `node-nailgun-client` package is abandoned, with its last publish over 7 years ago. The upstream Nailgun project itself was declared unmaintained in April 2023. This means there will be no further updates, bug fixes, or security patches, making it unsuitable for new projects or production use.","severity":"breaking","affected_versions":">=0.1.2"},{"fix":"Do not expose the Nailgun server or any client relying on it to untrusted networks or users. Implement strict network segmentation and access controls. Prioritize secure alternatives for inter-language communication.","message":"The original Nailgun protocol and server are explicitly noted as 'not secure.' They lack robust user authentication or authorization, allowing any program executed on the server to run with the same permissions as the Nailgun server process itself. This poses a significant security risk if exposed.","severity":"breaking","affected_versions":">=0.1.2"},{"fix":"Ensure your Node.js project is configured to use CommonJS modules (e.g., by omitting `\"type\": \"module\"` in `package.json` or by using `.cjs` file extensions) when integrating this package.","message":"This package is designed for Node.js environments and uses CommonJS `require()`. It does not support modern ECMAScript Modules (ESM) `import` syntax, which can lead to errors like 'require is not defined' in ESM-only contexts.","severity":"gotcha","affected_versions":">=0.1.2"},{"fix":"Test thoroughly with your target Node.js version. If compatibility issues arise, consider running the client in a containerized environment with an older, compatible Node.js version, or migrate to a more modern inter-process communication solution.","message":"Due to its age (published January 2019), `node-nailgun-client` may have compatibility issues with newer Node.js versions (e.g., Node.js 16, 18, 20+), particularly concerning stream APIs, internal module changes, or underlying system calls, potentially leading to unexpected behavior or crashes.","severity":"gotcha","affected_versions":">=0.1.2"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure your Node.js file or project is running as CommonJS. For example, rename your file to `.cjs` or ensure your `package.json` does not have `\"type\": \"module\"` set. If you must use ESM, you can try dynamic `import()`: `const nailgunClient = await import('node-nailgun-client');` but full compatibility is not guaranteed.","cause":"Attempting to use `require('node-nailgun-client')` in an ECMAScript Module (ESM) context where `require` is not globally available.","error":"require is not defined in ES module scope"},{"fix":"Verify that your Nailgun server is running and listening on the correct IP address and port. Check firewall rules that might be blocking the connection. Ensure the `address` and `port` options passed to `nailgunClient.exec` match your server configuration.","cause":"The Nailgun client attempted to connect to a server at the specified address and port, but no server was listening or the connection was actively refused.","error":"Error: connect ECONNREFUSED <address>:<port>"},{"fix":"Check the Nailgun server's logs (often found in `.pants.d/ng/<tool-name>/{stdout,stderr}` if used with a build system like Pants). Temporarily disabling Nailgun (if your build system supports it) can also force the underlying command to run directly, revealing the actual error message. Ensure the Java class path and arguments are correct for the command being executed.","cause":"The Nailgun client connected to the server, but the invoked Nailgun process failed to produce output or respond within the expected timeout period, often indicating the Java program itself crashed or failed to start correctly on the server.","error":"Failed to read nailgun output after X seconds!"},{"fix":"Examine the Nailgun server's logs for crashes or error messages. Ensure the server has sufficient resources (memory, CPU) and is stable. Check for network instability or server-side configuration issues that might cause premature connection closure.","cause":"The connection to the Nailgun server was abruptly terminated, often because the server crashed, was shut down unexpectedly, or an intermediary network device closed the connection.","error":"java.net.SocketException: Connection reset"}],"ecosystem":"npm"}