# What changed in ky

> 69 changes in ky 1 to 2 from its official release notes, upgrade guides and advisories: 12 breaking, 1 security, 17 new APIs and options. Each one cited. Sources checked 2026-10-17. HTML: https://unstale.sh/npm/ky/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## ky 2

### Breaking changes

- Invalid options and errors thrown by init hooks now reject the returned promise instead of throwing synchronously. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Invalid options now throw a TypeError naming the option instead of being silently ignored or failing later with an internal error. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- In init hooks, header names are now lowercase, so read and delete headers using lowercase names. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Malformed HTTP URLs are rejected when using baseUrl. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Hook errors are fatal outside retry handling. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- All hooks now receive a single state object instead of separate arguments; the beforeError state also includes request and options. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Calling .json() on an empty body or a 204 response now throws a parse error instead of returning an empty string. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Ky now requires Node.js 22. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Ky-specific properties are no longer present on the normalized options object passed to hooks. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Renames prefixUrl to prefix and allows leading slashes in input; prefix joins strings rather than resolving URLs. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- The option is renamed to prefix. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Query parameters now merge with those in the input URL instead of replacing them. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)

### Security

- Hardens retry behavior. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)

### New APIs and options

- Hooks can return `{options: {...}}` to change options such as timeout, fetch, or progress callbacks for subsequent attempts. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Limits the response body size in bytes after decompression; exceeding the limit throws a ResponseSizeError. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Upload progress and streamed Request bodies are supported in Bun and Deno. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- A response body exceeding maxResponseSize throws this new error. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Adds support for the QUERY method. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Adds standard URL resolution: leading-slash paths resolve from the origin root, while other paths resolve relative to the base path. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds a data property containing the automatically consumed and pre-parsed response body, making error details immediately available. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds the init hook. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds Standard Schema validation support for .json(). (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds the NetworkError class and tightens retry logic. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds a helper for .extend(). (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Adds an overall timeout that applies across all retries. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)

### Behavior and default changes

- beforeError hooks now run for errors thrown while reading the response body; a dropped connection during body reading is reported as a NetworkError. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- The hook now receives all error types, not only HTTPError, in its state object. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- The parseJson option now receives request and response context. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)

### Fixes and other changes

- Aborts and timeouts cancel requests returned from hooks, interrupt pending hooks and body reads, avoid being reported as NetworkError and retried in Chromium, and enforce totalTimeout when a response or body arrives after the deadline. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Option merging preserves class instances, matches header names case-insensitively, and prevents changes in extend callbacks and init hooks from leaking into other requests. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Setting fetch to window.fetch no longer throws “Illegal invocation” in browsers. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- isTimeoutError() and other type guards no longer match unrelated errors that share the same name. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Progress events now report the correct totalBytes for compressed responses and include response properties. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Using onUploadProgress no longer breaks uploads without request stream support or keepalive and no-cors requests. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- parseJson is no longer ignored by response.clone().json() or when using onDownloadProgress. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Edge cases in replaceOption() are fixed. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- The request property on Ky errors now refers to the request that was sent instead of an internal clone. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- When retry.shouldRetry returns true, Ky respects Retry-After and rate-limit headers. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Using searchParams with a Request input no longer drops its body or options such as credentials. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Types accept readonly arrays and explicit undefined for all options, allow custom error names, and correct the .clone() and .bytes() return types. (2.2.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.2.0)
- Fixes extend() dropping a numeric retry limit when merging with an object. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Allows parseJson to handle empty response bodies. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Fixes progress callbacks for requests and responses with empty bodies. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Improves handling of the Retry-After header. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Fixes handling of Safari errors with domains. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Fixes signal replacement when extending instances. (2.1.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.1.0)
- Prevents tuple searchParams mutations from leaking across init-hook requests. (2.0.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.2)
- Fixes URLSearchParams deletions in the init hook. (2.0.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.2)
- Improves compatibility with custom fetch implementations. (2.0.1) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.1)
- Fixes forwarding of fetch options. (2.0.1) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.1)
- Non-Error values returned by beforeError hooks are ignored. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- The hook is no longer skipped when it returns a Request. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Opaque responses from no-cors requests no longer cause an HTTPError. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)
- Unsupported request streams are now handled by gracefully ignoring onUploadProgress. (2.0.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v2.0.0)

## ky 1

### New APIs and options

- Add ky.retry() to force retries from afterResponse hooks. (1.14.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.0)
- Adds the context option. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)
- Adds the retry.jitter option. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)
- Adds the retry.retryOnTimeout option. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)
- Adds the retry.shouldRetry option. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)

### Behavior and default changes

- The type guard now includes ForceRetryError. (1.14.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.2)
- The throwHttpErrors option can now be a function. (1.14.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.0)
- beforeRetry hooks can now return a Request or Response. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)

### Fixes and other changes

- Fixes an empty context object being added to a merged json body. (1.14.3) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.3)
- Avoids awaiting response cancellation when a retry is forced. (1.14.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.2)
- Fixes response body cleanup after hooks run. (1.14.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.2)
- Fixes handling of uppercase retry.methods values and improves their typing. (1.14.2) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.2)
- Handles backoffLimit being undefined. (1.14.1) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.14.1)
- Fixes support for the next option in the Next.js edge runtime. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)
- Fixes compatibility with a non-standard Retry-After header. (1.13.0) — [release notes](https://github.com/sindresorhus/ky/releases/tag/v1.13.0)
