NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3791 most downloaded on npm
Tiny and elegant HTTP client based on the Fetch API
Last release 1 months ago
28 Aug 2026
Release timing varies
gaps range from 8 days to 5 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
100 releases · first in 2016
Add QUERY method support ( #873 ) 6edddd9
QUERY method support (#873) 6edddd9parseJson to handle empty bodies (#877) 294fe63baseUrl be60db5Retry-After handling (#874) 3419113signal replacement when extending instances (#880) 0bda554extend() dropping numeric retry limit when merging with an object (#867) 06375efOne column per quarter.
Fix init hook URLSearchParams deletions add0703
Improve compatibility with custom fetch implementations ( #858 ) 2971991
Unify hook signatures around a single state object ( #827 ) ecdd45e
{request, options, retryCount, ...} state object instead of separate arguments.prefixUrl to prefix, and allow leading slashes in input (#606) 1f2ad7fbeforeError hook receive all errors, not just HTTPError (#829) 101c74b.json() throw on empty bodies and 204 responses instead of returning an empty string (#854) 1b8e1ffsearchParams with input URL instead of replacing (#840) 29e78fetotalTimeout option for an overall timeout across all retries (#848) c20d7c7baseUrl option for standard URL resolution (#606) 1f2ad7f
baseUrl uses standard URL resolution: /users means origin-root, users means relative to the base path.prefix does simple string joining first, so /users and users both append to the prefix the same way. Use it only when you want that behavior.data property to HTTPError with pre-parsed response body (#823) 1341f5c
init hook (#841) 87c6740NetworkError class and tighten retry logic (#842) eaf0b80.json() (#830) 94741a9replaceOption helper for .extend() (#846) bb8412erequest and options to beforeError hook state (#835) 01e0b85parseJson option (#849) 3713ce8HTTPError for opaque responses from no-cors requests (#847) 1d15eb6onUploadProgress when request streams are unsupported (#845) 1e38ff4beforeRequest hooks being skipped when a Request is returned (#832) aec65dbbeforeError hooks (#833) a541fc0All hooks now receive a single state object instead of separate arguments.
hooks: {
- beforeRequest: [(request, options) => {
+ beforeRequest: [({request, options}) => {
request.headers.set('X-Custom', 'value');
}],
- afterResponse: [(request, options, response) => {
+ afterResponse: [({request, options, response}) => {
log(response.status);
}],
- beforeRetry: [({request, options, error, retryCount}) => {
+ beforeRetry: [({request, options, error, retryCount}) => {
// Same as before - beforeRetry already used an object
}],
- beforeError: [(error) => {
+ beforeError: [({error}) => {
return error;
}],
}prefixUrl renamed to prefix-ky('users', {prefixUrl: 'https://example.com/api/'});
+ky('users', {prefix: 'https://example.com/api/'});Leading slashes in input are now allowed with prefix. There's also a new baseUrl option for standard URL resolution, which you may prefer over prefix.
beforeError hook receives all errorsPreviously only received HTTPError. Now receives all error types. Use type guards:
+import {isHTTPError} from 'ky';
hooks: {
beforeError: [
- (error) => {
- const {response} = error;
+ ({error}) => {
+ if (isHTTPError(error)) {
+ const {response} = error;
+ }
return error;
}
]
}.json() on empty responses.json() now throws a parse error on empty bodies and 204 responses instead of returning an empty string. This aligns with native JSON.parse behavior and surfaces the real issue; your code expected JSON but the server sent none.
Check the status before calling .json() if you expect empty responses:
const response = await ky('https://example.com/api');
if (response.status !== 204) {
const data = await response.json();
}Ky-specific properties (hooks, json, parseJson, stringifyJson, searchParams, timeout, throwHttpErrors, fetch) are no longer available on the options object passed to hooks. If you need access to these values, store them in a variable outside the hook or use the context option to pass data between hooks.
searchParams mergingsearchParams now merges with existing query parameters in the input URL instead of replacing them.
// v1: searchParams replaces ?existing=1
// v2: searchParams merges with ?existing=1
ky('https://example.com?existing=1', {searchParams: {added: 2}});
// => https://example.com?existing=1&added=2HTTPError response bodyerror.response.json() and other body methods no longer work since the body is now automatically consumed. Use error.data instead, which has the pre-parsed response body immediately available.
-const body = await error.response.json();
-console.log(body.message);
+console.log(error.data.message);This fixes resource leaks when catching HTTPError without consuming the body (#633) and makes error details synchronously available (#642). We considered cloning the response to keep both paths working, but that doubles memory usage for error bodies and adds edge cases around locked/large streams for little benefit. error.response is still available for headers and status.
2.0.0-0.json() on empty responsesThe behavior changed again from the prerelease. .json() now throws instead of returning undefined for empty bodies and 204 responses. The return type is back to Promise<T> (no more | undefined).
Thanks to @sholladay for helping with this update.
Nothing published for this version
Fix empty context object being added to merged json body d7f7e73
Fix response body cleanup after hooks ( #809 ) 2bdbd59
Fix: Handle backoffLimit being undefined ( #796 ) 4fd8c28
Add ky.retry() to force retries from afterResponse hooks ( #779 ) 68a5228
ky.retry() to force retries from afterResponse hooks (#779) 68a5228throwHttpErrors option to be a function (#781) 84ff3b9Add context option ( #772 ) 1e749ba
context option (#772) 1e749ba
retry.shouldRetry option (#767) f0fdbd4retry.retryOnTimeout option (#767) f0fdbd4retry.jitter option (#760) 081c924beforeRetry hooks to return a Request or Response (#774) a51bb1enext option support (#775) caf78d2Add retry count to afterResponse and beforeError hooks (#763) 37fc250
afterResponse and beforeError hooks (#763) 37fc250beforeRequest hook (#754) b7572d0dispatcher option being ignored (#757) 5a3fc90hooks field incorrectly included in NormalizedOptions (#726) (#756) 0f2f00asearchParams option merging with URLSearchParams instances (#755) c847eecsignal merging when using both instance and request options (#751) 2b0a100content-type boundary regeneration when retrying in hooks (#752) d02b636https://github.com/sindresorhus/ky/compare/v1.11.0...v1.12.0
Improve progress events for onDownloadProgress and onUploadProgress (#736) 60958f9
onDownloadProgress and onUploadProgress (#736) 60958f9https://github.com/sindresorhus/ky/compare/v1.10.0...v1.11.0
Support undefined values for searchParams object (#729) a87d9e9
undefined values for searchParams object (#729) a87d9e9.json() (#731) 8cd79d3https://github.com/sindresorhus/ky/compare/v1.9.1...v1.10.0
Fix uploadProgress with form data (#725) 3a8f89c
uploadProgress with form data (#725) 3a8f89chttps://github.com/sindresorhus/ky/compare/v1.9.0...v1.9.1
Add .bytes() shortcut (#720) d112283
.bytes() shortcut (#720) d112283https://github.com/sindresorhus/ky/compare/v1.8.2...v1.9.0
Gracefully handle AbortSignal.any() not being available (#711) 24eec6f
AbortSignal.any() not being available (#711) 24eec6fhttps://github.com/sindresorhus/ky/compare/v1.8.1...v1.8.2
Improve reliability of cloned request cleanup (#693) 1f903ed
https://github.com/sindresorhus/ky/compare/v1.8.0...v1.8.1
Add `onUploadProgress` option (#632) a53fd34
onUploadProgress option (#632) a53fd34https://github.com/sindresorhus/ky/compare/v1.7.5...v1.8.0
Fix options.method being undefined in normalized options (#671) 762ea4c
options.method being undefined in normalized options (#671) 762ea4chttps://github.com/sindresorhus/ky/compare/v1.7.4...v1.7.5
Fix handling of a signal that is already aborted before the request begins (#663) 6d06338
https://github.com/sindresorhus/ky/compare/v1.7.3...v1.7.4
Fix memory leak from cloned responses (#661) 30e7afd
https://github.com/sindresorhus/ky/compare/v1.7.2...v1.7.3
Types: Mark ky.create() options as optional (#628) 8d2ca91
ky.create() options as optional (#628) 8d2ca91https://github.com/sindresorhus/ky/compare/v1.7.1...v1.7.2
Fix types for browsers (#623) 32a720d
https://github.com/sindresorhus/ky/compare/v1.7.0...v1.7.1
Add JSON generics to ky() and HTTPError (#619) f76c7cd
ky() and HTTPError (#619) f76c7cdhttps://github.com/sindresorhus/ky/compare/v1.6.0...v1.7.0
Add support for the RateLimit-Reset header (#618) 8531b05
RateLimit-Reset header (#618) 8531b05.extend() (#599) 0017053https://github.com/sindresorhus/ky/compare/v1.5.0...v1.6.0
Add `retry.afterStatusCodes` option (#598) 8764419
retry.afterStatusCodes option (#598) 8764419ky.extend() (#611) 9587c9dKyRequest and KyResponse types (#610) 8e171f5https://github.com/sindresorhus/ky/compare/v1.4.0...v1.5.0
Add request method and URL to error messages (#595) 36d0bd3
Retry-After time to retry.maxRetryAfter (#603) f0f9111https://github.com/sindresorhus/ky/compare/v1.3.0...v1.4.0
Add `stringifyJson` option (#579) 2eea67e
stringifyJson option (#579) 2eea67ehttps://github.com/sindresorhus/ky/compare/v1.2.4...v1.3.0
Fix request types for use with Node.js (#578) 10a4ec7
https://github.com/sindresorhus/ky/compare/v1.2.3...v1.2.4
TypeScript: Fix usage with exactOptionalPropertyTypes config and compatibility with TypeScript 5.4 (#565) 08f912d
exactOptionalPropertyTypes config and compatibility with TypeScript 5.4 (#565) 08f912dhttps://github.com/sindresorhus/ky/compare/v1.2.2...v1.2.3
Fix missing type dependency c0a4dfa
https://github.com/sindresorhus/ky/compare/v1.2.1...v1.2.2
Fix compatibility with Cloudflare Workers (#559) d8ee602
https://github.com/sindresorhus/ky/compare/v1.2.0...v1.2.1
Make types compatible with both DOM and Node.js (#543) 3cf5064
Input TypeScript type (#552) 4dd4077retryCount option retrying an incorrect amount (#547) 917ab12https://github.com/sindresorhus/ky/compare/v1.1.3...v1.2.0
Export the KyInstance type 16eb51d
KyInstance type 16eb51dhttps://github.com/sindresorhus/ky/compare/v1.1.2...v1.1.3
Fix multipart boundary mismatch (#540) 0e9d7bb
https://github.com/sindresorhus/ky/compare/v1.1.1...v1.1.2
Fix support for environments that add custom fetch options (#536) e93bc6d
fetch options (#536) e93bc6dhttps://github.com/sindresorhus/ky/compare/v1.1.0...v1.1.1
Add retry.delay option to control the time between retries (#533) c6181ef
retry.delay option to control the time between retries (#533) c6181efhttps://github.com/sindresorhus/ky/compare/v1.0.1...v1.1.0
Change Options and NormalizedOptions TypeScript types back to be interface 4d63a21
Options and NormalizedOptions TypeScript types back to be interface 4d63a21https://github.com/sindresorhus/ky/compare/v1.0.0...v1.0.1
Require Node.js 18 (when used in Node.js) a8a3a26
fetch.ky-universal is no longer needed.https://github.com/sindresorhus/ky/compare/v0.33.3...v1.0.0
Fix compatibility with native Fetch being disabled on Node.js (#494) 00e45d0
https://github.com/sindresorhus/ky/compare/v0.33.2...v0.33.3
Fix the name of the error when aborting a request (#482) ce8588d
https://github.com/sindresorhus/ky/compare/v0.33.1...v0.33.2
Fix compatibility with Unidici ae2fe07
https://github.com/sindresorhus/ky/compare/v0.33.0...v0.33.1
Add `retry.backoffLimit` option (#454) ab19baf
retry.backoffLimit option (#454) ab19bafhttps://github.com/sindresorhus/ky/compare/v0.32.2...v0.33.0
Fix the empty check for .json() (#466) bf9eca6
.json() (#466) bf9eca6https://github.com/sindresorhus/ky/compare/v0.32.1...v0.32.2
Don't return empty string for .json() if Transfer-Encoding is chunked (#464) 195e0e2
.json() if Transfer-Encoding is chunked (#464) 195e0e2https://github.com/sindresorhus/ky/compare/v0.32.0...v0.32.1
Parse empty response bodies without throwing when using .json() (#459) 1cc6bbb
.json() (#459) 1cc6bbbhttps://github.com/sindresorhus/ky/compare/v0.31.4...v0.32.0
Fix Firefox compatibility for the onDownloadProgress option bccbfdb
onDownloadProgress option bccbfdbhttps://github.com/sindresorhus/ky/compare/v0.31.3...v0.31.4
Fix Node.js compatibility 0b141f1
https://github.com/sindresorhus/ky/compare/v0.31.2...v0.31.3
Fix Chrome 105 compatibility (#451) 316fffe
https://github.com/sindresorhus/ky/compare/v0.31.1...v0.31.2
Fix copying response body with 204 status code when using onDownloadProgress (#444) d48ed95
onDownloadProgress (#444) d48ed95https://github.com/sindresorhus/ky/compare/v0.31.0...v0.31.1
Require Node.js 14 when used in Node.js e557973
BeforeRetryState type (#442) e4077b9onDownloadProgress (#441) f34fb1fhttps://github.com/sindresorhus/ky/compare/v0.30.0...v0.31.0
Allow overriding Content-Type header for JSON requests (#429) d00864f
Content-Type header for JSON requests (#429) d00864fhttps://github.com/sindresorhus/ky/compare/v0.29.0...v0.30.0
Add `beforeError` hook (#417) 616d276
beforeError hook (#417) 616d276https://github.com/sindresorhus/ky/compare/v0.28.7...v0.29.0
Fix source map generation (#396) b0e3001
https://github.com/sindresorhus/ky/compare/v0.28.6...v0.28.7
Fix types for TypeScript 4.4 (#384) ca20d65
https://github.com/sindresorhus/ky/compare/v0.28.5...v0.28.6
Export more TypeScript types ad991fa
https://github.com/sindresorhus/ky/compare/v0.28.4...v0.28.5
Fix missing hook method types for TypeScript (#353) 8fc2f22
https://github.com/sindresorhus/ky/compare/v0.28.3...v0.28.4
Fix incompatibility with New Relic (#351) 5f3c315
https://github.com/sindresorhus/ky/compare/v0.28.2...v0.28.3
Fix missing Options TypeScript type 3ad1eab
Options TypeScript type 3ad1eabmain field in package.json (#342) 1338996https://github.com/sindresorhus/ky/compare/v0.28.1...v0.28.2
Fix searchParams option TypeScript type (#344) 010b082
searchParams option TypeScript type (#344) 010b082https://github.com/sindresorhus/ky/compare/v0.28.0...v0.28.1
Your coding agent can read these notes before it upgrades. Set up the MCP server →