{"id":44312282,"url":"https://github.com/bricss/rekwest","last_synced_at":"2026-02-11T04:13:51.551Z","repository":{"id":57352641,"uuid":"379746801","full_name":"bricss/rekwest","owner":"bricss","description":"The robust request library that humanity deserves 🌐","archived":false,"fork":false,"pushed_at":"2026-02-07T14:00:11.000Z","size":1023,"stargazers_count":23,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-02-10T21:30:33.520Z","etag":null,"topics":["cookies","fetch","formdata","http","http-client","http-request","http2","http2-client","http2-request","multipart","multipart-formdata","multipart-uploads","nodejs","request"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/rekwest","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bricss.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-23T22:49:49.000Z","updated_at":"2026-02-07T14:00:14.000Z","dependencies_parsed_at":"2023-11-22T15:56:55.282Z","dependency_job_id":"a37af830-adca-4dc8-b6f7-33c3c3d67564","html_url":"https://github.com/bricss/rekwest","commit_stats":{"total_commits":63,"total_committers":1,"mean_commits":63.0,"dds":0.0,"last_synced_commit":"aec9dda10fad09b04bdd93916b45131d19954278"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bricss/rekwest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bricss%2Frekwest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bricss%2Frekwest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bricss%2Frekwest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bricss%2Frekwest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bricss","download_url":"https://codeload.github.com/bricss/rekwest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bricss%2Frekwest/sbom","scorecard":{"id":253618,"data":{"date":"2025-08-11","repo":{"name":"github.com/bricss/rekwest","commit":"b5ab58c53a0212e803af1ce4f943e5e09238d65a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Maintained","score":0,"reason":"1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yaml:1","Warn: no topLevel permission defined: .github/workflows/lint.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/bricss/rekwest/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/bricss/rekwest/ci.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/bricss/rekwest/lint.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yaml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/bricss/rekwest/lint.yaml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yaml:32","Warn: npmCommand not pinned by hash: .github/workflows/lint.yaml:26","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T09:03:53.829Z","repository_id":57352641,"created_at":"2025-08-17T09:03:53.829Z","updated_at":"2025-08-17T09:03:53.829Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29327088,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cookies","fetch","formdata","http","http-client","http-request","http2","http2-client","http2-request","multipart","multipart-formdata","multipart-uploads","nodejs","request"],"created_at":"2026-02-11T04:13:50.438Z","updated_at":"2026-02-11T04:13:51.542Z","avatar_url":"https://github.com/bricss.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"The robust request library that humanity deserves 🌐\n---\nThis package provides highly likely functional and **easy-to-use** abstraction atop of\nnative [http(s).request](https://nodejs.org/api/https.html#httpsrequesturl-options-callback)\nand [http2.request](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options).\n\n## Abstract\n\n* Fetch-alike 🥏\n* Cool-beans 🫐 config options (with defaults)\n* Automatic HTTP/2 support (ALPN negotiation) 💼\n* Automatic or opt-in body parse (with non-UTF-8 charset decoding) 🉑\n* Automatic and simplistic `Cookies` treatment (with **TTL** support) 🍪\n* Automatic body decoding (and opt-in request body encoding) 🗜️\n* Better error management 🚥\n* Built-in streamable `FormData` interface 🔌\n* Support redirects \u0026 retries with fine-grained tune-ups 🪛\n* Support plenty request body types (include blobs \u0026 streams) 📦\n* Support both CJS and ESM module systems 🧩\n* Fully promise-able and pipe-able 🔗\n* Zero dependencies 🗽\n\n## Prerequisites\n\n* Node.js `\u003e= 20.0.0`\n\n## Installation\n\n```bash\nnpm install rekwest --save\n```\n\n### Usage\n\n```javascript\nimport rekwest, { constants } from 'rekwest';\n\nconst {\n  HTTP2_HEADER_AUTHORIZATION,\n  HTTP2_HEADER_CONTENT_ENCODING,\n  HTTP2_METHOD_POST,\n  HTTP_STATUS_OK,\n} = constants;\n\nconst url = 'https://somewhe.re/somewhat/endpoint';\n\nconst res = await rekwest(url, {\n  body: { celestial: 'payload' },\n  headers: {\n    [HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',\n    [HTTP2_HEADER_CONTENT_ENCODING]: 'br',  // enables: body encoding\n    /** [HTTP2_HEADER_CONTENT_TYPE]\n     * is undue for\n     * Array/Blob/File/FormData/Object/URLSearchParams body types\n     * and will be set automatically, with an option to override it here\n     */\n  },\n  method: HTTP2_METHOD_POST,\n});\n\nconsole.assert(res.statusCode === HTTP_STATUS_OK);\nconsole.info(res.headers);\nconsole.log(res.body);\n```\n\n---\n\n```javascript\nimport { Readable } from 'node:stream';\nimport rekwest, {\n  constants,\n  Blob,\n  File,\n  FormData,\n} from 'rekwest';\n\nconst {\n  HTTP2_HEADER_AUTHORIZATION,\n  HTTP2_HEADER_CONTENT_ENCODING,\n  HTTP2_METHOD_POST,\n  HTTP_STATUS_OK,\n} = constants;\n\nconst blob = new Blob(['bits']);\nconst file = new File(['bits'], 'file.dab');\nconst readable = Readable.from('bits');\n\nconst fd = new FormData({\n  aux: Date.now(),  // either [[key, value]] or kv sequenceable\n});\n\nfd.append('celestial', 'payload');\nfd.append('blob', blob, 'blob.dab');\nfd.append('file', file);\nfd.append('readable', readable, 'readable.dab');\n\nconst url = 'https://somewhe.re/somewhat/endpoint';\n\nconst res = await rekwest(url, {\n  body: fd,\n  headers: {\n    [HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',\n    [HTTP2_HEADER_CONTENT_ENCODING]: 'zstd',  // enables: body encoding\n  },\n  method: HTTP2_METHOD_POST,\n});\n\nconsole.assert(res.statusCode === HTTP_STATUS_OK);\nconsole.info(res.headers);\nconsole.log(res.body);\n```\n\n### API\n\n#### `rekwest(url[, options])`\n\n* `url` **{string | URL}** The URL to send the request to\n* `options` **{Object}**\n  Extends [http(s).RequestOptions](https://nodejs.org/api/https.html#httpsrequesturl-options-callback) along with\n  extra [http2.ClientSessionOptions](https://nodejs.org/api/http2.html#http2connectauthority-options-listener)\n  \u0026 [http2.ClientSessionRequestOptions](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options)\n  and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tlsconnectoptions-callback)\n  for HTTP/2 attunes\n  * `baseURL` **{string | URL}** The base URL to use in cases where `url` is a relative URL\n  * `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |\n    FormData | Iterator | Object | Readable | ReadableStream | SharedArrayBuffer | URLSearchParams}** The body to send\n    with the request\n  * `bufferBody` **{boolean}** `Default: false` Toggles the buffering of the streamable request bodies for redirects and\n    retries\n  * `cookies` **{boolean | Array\u003c[k, v]\u003e | Array\u003cstring\\\u003e | Cookies | Object | URLSearchParams}** `Default: true` The\n    cookies to add to\n    the request\n  * `cookiesTTL` **{boolean}** `Default: false` Controls enablement of TTL for the cookies cache\n  * `credentials` **{include | omit | same-origin}** `Default: same-origin` Controls credentials in case of cross-origin\n    redirects\n  * `decodersOptions` **{Object}** Configures decoders options, e.g.: `brotli`, `zstd`, `zlib`\n  * `digest` **{boolean}** `Default: true` Controls whether to read the response stream or add a mixin\n  * `encodersOptions` **{Object}** Configures encoders options, e.g.: `brotli`, `zstd`, `zlib`\n  * `follow` **{number}** `Default: 20` The number of redirects to follow\n  * `h2` **{boolean}** `Default: false` Forces the use of HTTP/2 protocol\n  * `headers` **{Object}** The headers to add to the request\n  * `maxRetryAfter` **{number}** The upper limit of `retry-after` header. If unset, it will use `timeout` value\n  * `parse` **{boolean}** `Default: true` Controls whether to parse response body or return a buffer\n  * `redirect` **{error | follow | manual}** `Default: follow` Controls the redirect flows\n  * `retry` **{Object}** Represents the retry options\n    * `attempts` **{number}** `Default: 0` The number of retry attempts\n    * `backoffStrategy` **{string}** `Default: interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)`\n      The backoff strategy algorithm that increases logarithmically. To fixate set value to `interval * 1`\n    * `errorCodes` **{string[]}**\n      `Default: ['ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'ERR_HTTP2_STREAM_ERROR']`\n      The list of error codes to retry on\n    * `interval` **{number}** `Default: 1e3` The initial retry interval\n    * `retryAfter` **{boolean}** `Default: true` Controls `retry-after` header receptiveness\n    * `statusCodes` **{number[]}** `Default: [429, 500, 502, 503, 504]` The list of status codes to retry on\n  * `stripTrailingSlash` **{boolean}** `Default: false` Controls whether to strip trailing slash at the end of the URL\n  * `thenable` **{boolean}** `Default: false` Controls the promise resolutions\n  * `timeout` **{number}** `Default: 3e5` The number of milliseconds a request can take before termination\n  * `trimTrailingSlashes` **{boolean}** `Default: false` Controls whether to trim trailing slashes within the URL\n* **Returns:** Promise that resolves to\n  extended [http.IncomingMessage](https://nodejs.org/api/http.html#class-httpincomingmessage)\n  or [http2.ClientHttp2Stream](https://nodejs.org/api/http2.html#class-clienthttp2stream) which is respectively\n  readable and duplex streams\n  * if `digest: true` \u0026 `parse: true`\n    * `body` **{string | Array | Buffer | Object}** The body based on its content type\n  * if `digest: false`\n    * `arrayBuffer` **{AsyncFunction}** Reads the response and returns **ArrayBuffer**\n    * `blob` **{AsyncFunction}** Reads the response and returns **Blob**\n    * `body` **{AsyncFunction}** Reads the response and returns **Buffer** if `parse: false`\n    * `bytes` **{AsyncFunction}** Reads the response and returns **Uint8Array**\n    * `json` **{AsyncFunction}** Reads the response and returns **Object**\n    * `text` **{AsyncFunction}** Reads the response and returns **String**\n  * `bodyUsed` **{boolean}** Indicates whether the response was read or not\n  * `cookies` **{undefined | Cookies}** The cookies sent and received with the response\n  * `headers` **{Object}** The headers received with the response\n  * `httpVersion` **{string}** Indicates a protocol version negotiated with the server\n  * `ok` **{boolean}** Indicates if the response was successful (statusCode: **200-299**)\n  * `redirected` **{boolean}** Indicates if the response is the result of a redirect\n  * `statusCode` **{number}** Indicates the status code of the response\n  * `trailers` **{undefined | Object}** The trailer headers received with the response\n\n---\n\n#### `rekwest.defaults`\n\nThe object to fulfill with default [options](#rekwesturl-options).\n\n---\n\n#### `rekwest.extend(options)`\n\nThe method to extend default [options](#rekwesturl-options) per instance.\n\n```javascript\nimport rekwest, { constants } from 'rekwest';\n\nconst {\n  HTTP_STATUS_OK,\n} = constants;\n\nconst rk = rekwest.extend({\n  baseURL: 'https://somewhe.re',\n});\n\nconst signal = AbortSignal.timeout(1e4);\nconst url = '/somewhat/endpoint';\n\nconst res = await rk(url, {\n  signal,\n});\n\nconsole.assert(res.statusCode === HTTP_STATUS_OK);\nconsole.info(res.headers);\nconsole.log(res.body);\n```\n\n---\n\n#### `rekwest.stream(url[, options])`\n\nThe method with limited functionality to use with streams and/or pipes.\n\n* No automata (redirects \u0026 retries)\n* Pass `h2: true` in options to use HTTP/2 protocol\n  * Use `ackn({ url: URL })` method in advance to check the available protocols\n\n```javascript\nimport fs from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\nimport rekwest, {\n  ackn,\n  constants,\n} from 'rekwest';\n\nconst {\n  HTTP2_METHOD_POST,\n} = constants;\n\nconst url = new URL('https://somewhe.re/somewhat/endpoint');\nconst options = await ackn({ url });\n\nawait pipeline(\n  fs.createReadStream('/path/to/read/inlet.xyz'),\n  rekwest.stream(url, { ...options, method: HTTP2_METHOD_POST }),\n  fs.createWriteStream('/path/to/write/outlet.xyz'),\n);\n```\n\n---\n\nFor more details, please check tests (coverage: **\u003e97%**) in the repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbricss%2Frekwest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbricss%2Frekwest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbricss%2Frekwest/lists"}