Skip to content

Add onDownloadProgress to track the download progress of responses - #115

Merged
MattCCC merged 3 commits into
masterfrom
download-progress
Sep 27, 2026
Merged

MattCCC merged 3 commits into
masterfrom
download-progress

Conversation

@MattCCC

@MattCCC MattCCC commented Sep 27, 2026

Copy link
Copy Markdown
Owner

This pull request adds onDownloadProgress, the counterpart of onUploadProgress, to track the progress of a response body while it's being received, e.g. to show a progress bar for file downloads.

✨ Features & Improvements

  • Added onDownloadProgress: it's called with loaded (the bytes received so far), total (the bytes to receive, if known) and progress (from 0 to 1, if the total is known) whenever a part of the response body arrives.
  • Streaming: the body of native responses is counted while it's received and parsed, so the progress follows the download. It works wherever fetch() streams response bodies, i.e. in all modern browsers, Node.js, Deno and Bun, and also for bodies read by a custom parser.
  • Total size: taken from the Content-Length header, and unknown for compressed responses, whose Content-Length is the compressed size. The progress never goes beyond 1, e.g. when browsers hide the Content-Encoding header of cross-origin responses.
  • The response keeps its status, headers, URL, redirected and type. Responses without a body and responses of custom fetchers that aren't native Response objects are left as they are.
  • Exported the DownloadProgress type.
  • Documented in a new "Download Progress" section.

🧪 Tests

  • The progress of a body that arrives in parts, an unknown total without Content-Length and for compressed responses, and a progress that doesn't go beyond 1.
  • The details of the response, bodies read by a custom parser, the responses of uploads, responses without a body, responses of custom fetchers, and responses left as they are without onDownloadProgress.
  • Coverage stays at 100%.

📦 Bundle Size

The core bundles grow by about 0.1 KB (brotli). The size limits are raised to fit this and the other pull requests opened alongside it, so that they can be merged in any order.


Generated by Claude Code

…se bodies

onDownloadProgress is called with the loaded and total bytes and the progress from 0 to 1 whenever a part of a response body arrives. The body of native responses is counted while it's received and parsed, so it works wherever fetch() streams response bodies, including responses parsed by a custom parser. The total comes from the Content-Length header, and is unknown for compressed responses, whose Content-Length is the compressed size. The progress never goes beyond 1, as browsers may hide the Content-Encoding header of cross-origin responses. Responses without a body and responses of custom fetchers that aren't native are left as they are.
Core bundles 7.75 KB -> 8.75 KB, dist/react/index.mjs 10.75 KB -> 11.75 KB and dist/react/index.js 11.75 KB -> 12.75 KB. The limits fit this and the other PRs opened alongside it (abort signal fix, ETag revalidation, retry jitter and methods, onDownloadProgress, responseType, focusThrottleInterval, initialData and typed OpenAPI endpoints), which add about 1 KB together, so that they can be merged in any order.
@github-actions

Copy link
Copy Markdown

size-limit report 📦

Path Size
dist/browser/index.mjs 7.42 KB (+1.51% 🔺)
dist/browser/index.global.js 7.61 KB (+1.73% 🔺)
dist/node/index.js 7.51 KB (+1.63% 🔺)
dist/react/index.mjs 10.45 KB (+1.15% 🔺)
dist/react/index.js 11.36 KB (+1.27% 🔺)

@MattCCC
MattCCC merged commit 2516396 into master Sep 27, 2026
14 checks passed
@MattCCC
MattCCC deleted the download-progress branch September 27, 2026 20:18
@MattCCC MattCCC mentioned this pull request Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants