Node 22+ ESM-only support and refined upload, proxy, and error handling
Published: August 12, 2026
@sanity/client v8 is the first step in modernizing the JavaScript client. For most users this will be an uneventful upgrade. The main exception is anyone still running end-of-life Node.js versions. Benefits include less maintenance overhead, fewer dependencies, and better stack traces.
What changed
Node 22.12+ required and ESM-only
Node 20 went out of LTS in April 2026 and is no longer supported. The minimum Node version is 22.12. The package now ships as ESM only. The CommonJS bundle, ./dist/*.cjs files, and the CJS main entry are gone.
This is a soft change for most users: Node 22.12+ supports require(esm) natively, so existing code like const {createClient} = require('@sanity/client') continues to work without any changes. ESM import is still preferred. If you cannot move off an older Node version, stay on v7.
Upload progress events
HttpRequestEvent, ResponseEvent, and ProgressEvent are removed. Observable asset uploads now use dedicated event types: UploadEvent<T>, UploadResponseEvent<T>, and UploadProgressEvent. The type discriminants ('response'/'progress') and the progress event shape are unchanged.
Progress events now fire only in browsers. In Node and edge runtimes, observable uploads emit only the terminal response event. The Promise-based client.assets.upload() is unchanged.
Proxy configuration
The proxy option can no longer be passed with individual requests. Configure proxy on the client config instead (Node.js only), or set HTTP_PROXY, HTTPS_PROXY, or NO_PROXY before the process starts. Proxy environment variables are read once at startup, not per-request.
The uri option removed — use url
The legacy uri alias in client.request() is gone. Use url instead. This is a rename only; the value and behavior are unchanged.
Error messages now include HTTP status text
ClientError and ServerError messages now read 'HTTP 400 Bad Request' rather than 'HTTP 400'. If you match error messages in tests, update your patterns. The structured fields on the error (statusCode, responseBody, etc.) are unchanged.
UMD bundle removed
The UMD bundle is no longer included in the distribution. Use a bundler or a service like esm.sh instead.
DNS errors retried
DNS ENOTFOUND errors are now retried for idempotent requests (GET, HEAD) with standard exponential backoff. Pass maxRetries: 0 to fail immediately instead.
Other removals
unstable__adapter and unstable__environment exports are removed. The _requestHandler client config option and RequestHandler type are removed. The requester client config option is removed. typesVersions declarations are removed. Use TypeScript moduleResolution set to node16, nodenext, or bundler.
Migration guide
See the full migration guide on GitHub for step-by-step instructions on each breaking change.