{"id":15715,"library":"needle","title":"Needle HTTP Client","description":"Needle is a lightweight and performant HTTP client for Node.js, designed for various HTTP/HTTPS requests, including API interactions, file uploads, and data streaming. The current stable version is 3.5.0, and the project maintains a moderate release cadence, focusing on stability, bug fixes, and incremental feature enhancements, with major versions occurring less frequently. Key differentiators include its minimal dependency footprint, built-in support for streaming gzip, deflate, and brotli decompression (Node 10+), and automatic JSON/XML parsing. Its API is flexible, supporting traditional callbacks, modern Promises, and direct stream piping, allowing developers to choose the paradigm best suited for their application. Needle also handles essential features like Basic & Digest authentication, multipart form-data uploads, and HTTP proxy forwarding, positioning itself as an efficient alternative for quick and reliable HTTP operations in Node.js environments.","status":"active","version":"3.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/tomas/needle","tags":["javascript","http","https","simple","request","client","multipart","upload","proxy"],"install":[{"cmd":"npm install needle","lang":"bash","label":"npm"},{"cmd":"yarn add needle","lang":"bash","label":"yarn"},{"cmd":"pnpm add needle","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for streaming non-UTF-8 charset decoding.","package":"iconv-lite","optional":false}],"imports":[{"note":"For ESM, 'needle' is the default export, typically used with `import needle from 'needle';`. For CommonJS, use `const needle = require('needle');`. The imported 'needle' object is itself callable for Promise-based requests (e.g., `needle('put', ...)`) and exposes methods like `.get` and `.post`.","wrong":"const needle = require('needle');","symbol":"needle","correct":"import needle from 'needle';"},{"note":"The `.get` method is a property of the default `needle` export, not a named export. Ensure you import the default export first.","wrong":"const { get } = require('needle');","symbol":"needle.get","correct":"import needle from 'needle';\nneedle.get('url', callback);"},{"note":"Similar to `.get`, the `.post` method is accessed via the default `needle` export; it is not a named export.","wrong":"const { post } = require('needle');","symbol":"needle.post","correct":"import needle from 'needle';\nneedle.post('url', data, options, callback);"}],"quickstart":{"code":"import needle from 'needle';\nimport https from 'https'; // Required for AgentOptions if using self-signed certs\n\nconst agent = new https.Agent({\n  rejectUnauthorized: process.env.NODE_ENV === 'production' // Example TLS option\n});\n\nconst data = {\n  username: 'testuser',\n  password: process.env.TEST_PASSWORD ?? 'securepassword123'\n};\n\nneedle('post', 'https://httpbin.org/post', data, { json: true, agent: agent })\n  .then(response => {\n    if (response.statusCode === 200) {\n      console.log('Request successful:', response.body.json);\n    } else {\n      console.error('Request failed with status:', response.statusCode);\n    }\n  })\n  .catch(err => {\n    console.error('An error occurred during POST request:', err.message);\n  });\n\n// Example using callback style for a GET request\nneedle.get('https://httpbin.org/get', { agent: agent }, (error, response) => {\n  if (error) {\n    console.error('GET request error:', error.message);\n    return;\n  }\n  if (response.statusCode === 200) {\n    console.log('GET successful:', response.body.json);\n  } else {\n    console.error('GET failed with status:', response.statusCode);\n  }\n});","lang":"typescript","description":"Demonstrates a Promise-based POST request for JSON data and a callback-based GET request, including basic error handling and HTTPS agent options."},"warnings":[{"fix":"If buffering is desired, ensure a callback is provided to `needle.get`/`post` or use the Promise API. If streaming, pipe the response to a writable stream or listen to 'data' events directly.","message":"When using callbacks or Promises, Needle buffers the entire response body into `response.body`. If no callback is provided and you are streaming directly (e.g., `.pipe()`), `response.body` will be skipped. Ensure you handle `response.body` or the stream appropriately based on your usage pattern.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Carefully test existing implementations after upgrading from pre-3.0.0 versions. Review Node.js documentation for changes in deprecated APIs if encountering unexpected behavior.","message":"Version 3.0.0 introduced significant internal changes, including the removal of deprecated Node.js API usage and the replacement of `.pipe` calls with `stream.pipeline` internally. While public API changes were not explicitly documented as breaking for most users, code relying on specific internal Node.js deprecated APIs or subtle stream behaviors might require adjustments.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade Node.js to version 10.16.0 or higher to utilize Brotli compression. Ensure your deployment environment meets this minimum requirement if Brotli is critical for your application.","message":"Brotli decompression is only supported on Node.js versions 10.16.0 or above. If Needle receives a Brotli-encoded response on an earlier Node.js version, it will not be able to decompress it, potentially leading to unreadable response bodies.","severity":"gotcha","affected_versions":"<10.16.0"},{"fix":"If you are on Node.js <18 and rely on non-UTF-8 decoding, you may need to explicitly pin your `iconv-lite` dependency to a version older than `0.7.0` (e.g., `<0.7.0`). Otherwise, upgrade your Node.js environment to version 18 or newer.","message":"The `iconv-lite` dependency, which Needle uses for streaming non-UTF-8 charset decoding, had a breaking change in its v0.7.0 and v0.8.0 releases, dropping support for Node.js versions prior to 18. If your project uses an older Node.js runtime and `npm` resolves `iconv-lite` to v0.7.0+ (or v0.8.0+), charset decoding might fail or produce errors.","severity":"gotcha","affected_versions":"<18.0.0 (for `iconv-lite` v0.7.0+)"},{"fix":"Always provide a string path to the local file (e.g., `{ file: '/path/to/my/image.png', content_type: 'image/png' }`) for the `file` option in multipart uploads.","message":"For multipart form-data uploads, the `file` option within the data object expects a string path to the file on the local filesystem, not a Node.js `fs.ReadStream`. Needle handles opening and streaming the file internally from the provided path. Providing a stream directly might lead to unexpected behavior or errors.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Run `npm install needle` or `yarn add needle` in your project directory to install the package.","cause":"The 'needle' package is not installed or not resolvable by the module loader in the current environment.","error":"Error: Cannot find module 'needle'"},{"fix":"Use `import needle from 'needle';` instead of `const needle = require('needle');` when working in an ESM environment (e.g., in a `.mjs` file or a project with `\"type\": \"module\"` in `package.json`).","cause":"You are attempting to use `require('needle')` within an ECMAScript Module (ESM) context, which does not natively support CommonJS `require` calls without specific configuration.","error":"ERR_REQUIRE_ESM"},{"fix":"While often transient, ensure robust error handling and retry mechanisms. Needle versions 3.1.0+ include fixes to silence these errors after connection close, but the underlying network issue might persist. Check server logs and network conditions. For persistent connections, consider adding `keepAlive: true` in options for multiple requests to the same host.","cause":"The remote server unexpectedly terminated the connection. This can be caused by various network issues, server-side misconfigurations, or aggressive firewall rules.","error":"Error: read ECONNRESET"},{"fix":"Verify that the encoding name is correct and supported by `iconv-lite`. If using an older Node.js version (prior to 18), you might need to explicitly pin your `iconv-lite` dependency to a version older than `0.7.0` to ensure compatibility.","cause":"Needle relies on `iconv-lite` for non-UTF-8 character set decoding, and the specified encoding is either not recognized by `iconv-lite` or the `iconv-lite` version is incompatible with your Node.js runtime.","error":"Unsupported encoding: [encoding name]"}],"ecosystem":"npm"}