{"id":4733,"url":"https://github.com/react-native-community/fetch","last_synced_at":"2025-08-04T02:31:32.698Z","repository":{"id":48296030,"uuid":"246343267","full_name":"react-native-community/fetch","owner":"react-native-community","description":"A fetch API polyfill for React Native with text streaming support.","archived":false,"fork":true,"pushed_at":"2023-06-07T21:25:53.000Z","size":1305,"stargazers_count":79,"open_issues_count":14,"forks_count":11,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-02T00:51:43.557Z","etag":null,"topics":["fetch","fetch-api","polyfill","react-native","streams","streams-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"JakeChampion/fetch","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-native-community.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-10T15:50:01.000Z","updated_at":"2024-11-07T17:28:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/react-native-community/fetch","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-community%2Ffetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-community%2Ffetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-community%2Ffetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-community%2Ffetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-native-community","download_url":"https://codeload.github.com/react-native-community/fetch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228587347,"owners_count":17941442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["fetch","fetch-api","polyfill","react-native","streams","streams-api"],"created_at":"2024-01-05T20:17:21.665Z","updated_at":"2024-12-07T09:30:55.281Z","avatar_url":"https://github.com/react-native-community.png","language":"JavaScript","readme":"# fetch\n\n[![npm version][npm-image]][npm-url] [![ci][github-ci-image]][github-ci-url]\n\n[npm-url]:https://www.npmjs.com/package/react-native-fetch-api\n[npm-image]:https://img.shields.io/npm/v/react-native-fetch-api.svg\n[github-ci-url]:https://github.com/react-native-community/fetch/actions\n[github-ci-image]:https://github.com/react-native-community/fetch/workflows/Node%20CI/badge.svg\n\n\u003e A fetch API polyfill for React Native with text streaming support\n\nThis is a fork of GitHub's fetch [polyfill](https://github.com/github/fetch), the fetch implementation React Native currently [provides](https://github.com/facebook/react-native/blob/master/Libraries/Network/fetch.js). This project features an alternative fetch implementation directy built on top of React Native's [Networking API](https://github.com/facebook/react-native/tree/master/Libraries/Network) instead of `XMLHttpRequest` for performance gains. At the same time, it aims to fill in some gaps of the [WHATWG specification](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for fetch, namely the support for text streaming.\n\nIn practice, this implementation is a drop-in replacement to GitHub's polyfill as it closely follows its implementation. Do not use this implementation if your application does not require to stream text.\n\n## Motivation\n\nGitHub's fetch polyfill, originally designed with the intention to be used in web browsers without support for the fetch standard, most notably does not support the consumption of a response body as a stream.\n\nHowever, as React Native does not yet provide direct access to the underlying byte stream for responses, we either have to fallback to [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) or React Native's networking API for [iOS](https://github.com/facebook/react-native/blob/v0.63.4/Libraries/Network/RCTNetworking.ios.js) and [Android](https://github.com/facebook/react-native/blob/v0.63.4/Libraries/Network/RCTNetworking.android.js). Currently, only strings can be transfered through the bridge, thus binary data has to be base64-encoded ([source](https://github.com/react-native-community/discussions-and-proposals/issues/107)) and while React Native's XHR provides [progress events](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/progress_event) to receive incremental data, it concatenates the response string as data comes in. Although [very inefficient](https://github.com/jonnyreeves/fetch-readablestream/blob/cabccb98788a0141b001e6e775fc7fce87c62081/src/defaultTransportFactory.js#L33), the response can be sliced up, each chunk encoded into its UTF-8 representation with [TextEncoder](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder) and finally enqueued to the stream.\n\nInstead of relying on `XMLHttpRequest`, which degrades performance, we remove it out of the equation and have fetch interact with React Native's Networking API directly instead. To make `Response.body` work, `ReadableStream`'s controller was integrated with native progress events. It's important to stress that progress events are only fired when the native response type is set to `text` (https://github.com/facebook/react-native/blob/v0.63.4/Libraries/Network/RCTNetworking.mm#L544-L547), therefore limiting streaming to text-only transfers. If you wish to consume binary data, either `blob` or `base64` response types have to be used. In this case, the downside is that the final response body is read as a whole and enqueued to the stream's controller as a single chunk. There is no way to read a partial response of a binary transfer.\n\nFor more context, read the following:\n- https://github.com/github/fetch/issues/746\n- https://github.com/facebook/react-native/issues/27741\n- https://hpbn.co/xmlhttprequest/#streaming-data-with-xhr\n\nRelated:\n- https://github.com/react-native-community/discussions-and-proposals/issues/99\n\n## Requirements\n\nReact Native v0.62.0+ is the minimum version supported where the [Networking API has been made public](https://github.com/facebook/react-native/commit/42ee5ec93425c95dee6125a6ff6864ec647636aa).\n\nThis implementation depends on the following web APIs which are not currently available in React Native:\n\n- [`TextEncoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/TextEncoder) \n- [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/TextDecoder)\n- [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)\n\nIt should be possible remove the dependency on `TextEncoder` and `TextDecoder`, but not on `ReadableStream`. Either way, beware the bundle size of your application will inevitable increase.\n\nTo polyfill the above APIs, use [react-native-polyfill-globals](https://github.com/acostalima/react-native-polyfill-globals).\n\n## Install\n\n```\n$ npm install react-native-fetch-api --save\n```\n\n## Setup\n\nThe APIs provided by GitHub's implementation in React Native  have to be replaced by those provided by this implementation. To do so, check and install [react-native-polyfill-globals](https://github.com/acostalima/react-native-polyfill-globals) and follow the instructions therein.\n\n## Usage\n\nNo need to import anything after the [setup](#setup) is done. All APIs will be available globally.\n\nExample:\n\n```js\nfetch('https://jsonplaceholder.typicode.com/todos/1')\n  .then(response =\u003e response.json())\n  .then(json =\u003e console.log(json))\n```\n\nCheck fetch's [official documentation](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to learn more about the concepts and extended usage.\n\n### Enable text streaming\n\nA non-standard option was added to `fetch` to enable incremental events in React Native's networking layer.\n\n```js\nfetch('https://jsonplaceholder.typicode.com/todos/1', { reactNative: { textStreaming: true } })\n  .then(response =\u003e response.body)\n  .then(stream =\u003e ...)\n```\n### Aborting requests\n\nIt's possible to [abort an on-going request](https://developers.google.com/web/updates/2017/09/abortable-fetch) and React Native already supports [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController), so there is no need for a polyfill.\n\n```js\nconst controller = new AbortController();\n\nfetch('https://jsonplaceholder.typicode.com/todos/1', { signal: controller.signal })\n  .then(response =\u003e response.json())\n  .then(json =\u003e console.log(json))\n```\n\nLearn more about aborting fetch at https://developers.google.com/web/updates/2017/09/abortable-fetch.\n\n### Cookies\n\nThere is no concept of Cross-Origin Resource Sharing (CORS) in native apps. React Native only accepts a boolean value for the [`credentials`](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) option. As such, to send cookies you can either use `same-origin` and `include`.\n\nThe `Set-Cookie` response header returned from the server is a [forbidden header name](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name) and therefore can't be programmatically read with `response.headers.get()`. Instead, the platform's native networking stack automatically manages cookies for you.\n\nIf you run into issues with cookie-based authentication, read the following:\n- https://reactnative.dev/docs/network#known-issues-with-fetch-and-cookie-based-authentication\n- https://build.affinity.co/persisting-sessions-with-react-native-4c46af3bfd83\n- https://medium.com/locastic/react-native-cookie-based-authentication-80ee18f4c71b\n\nAlternatively, you may consider using the [react-native-cookies](https://github.com/react-native-cookies/cookies).\n\n### Request caching directive\n\nThe only values supported for the [`cache`](https://developer.mozilla.org/en-US/docs/Web/API/Request/cache) option are `no-cache` and `no-store` and Both achieve exactly the same result. All other values are ignored. Following GitHub's implementation, a cache-busting mechanism is provided by using the query parameter `_` which holds the number of milliseconds elapsed since the Epoch when either `no-cache` or `no-store` are specified.\n\n### Redirect modes directive\n\nThe fetch specification defines these values for the [`redirect`](https://developer.mozilla.org/en-US/docs/Web/API/Request/redirect) option: `follow` (the default), `error`, and `manual`. React Native does not accept such option but it does transparently follow a redirect response given the `Location` header for 30x status codes.\n\n## Tests\n\nTo run the test suite, you must use [`react-native-test-runner`](https://github.com/acostalima/react-native-test-runner) CLI. Run the `run-tests.js` wrapper script to spin up a local HTTP server to execute the networking tests against.\n\n### iOS\n\n```\n$ ./run-tests.js --platform ios --simulator '\u003csimulator\u003e' test/index.js \n```\n\nWhere `\u003csimulator\u003e` can be a combination of a device type and iOS version, e.g. `iPhone 11 (14.1)`, or a device UUID.\nCheck which simulators are available in your system by running the following command:\n\n```\n$ xcrun xctrace list devices\n```\n\n### Android\n\n```\n$ ./run-tests.js --platform android --emulator '\u003cemulator\u003e' test/index.js \n```\n\nWhere `\u003cemulator\u003e` is the name of the Android Virtual Device (AVD), e.g. `Pixel_API_28_AOSP`.\nCheck which emulators are available in your system by running the following command:\n\n```\n$ emulator -list-avds\n```\n\n","funding_links":[],"categories":["Components"],"sub_categories":["Backend"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-native-community%2Ffetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-native-community%2Ffetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-native-community%2Ffetch/lists"}