Library / SDK
async-library/react-async avatar
async-library/react-async

react-async: a data loader whose last tagged release is from 2020 and whose default branch is not main

🍾 Flexible promise-based React data loader

2,140 stars86 forksJavaScriptISC

At a glance

What is it?
A promise-based React data loader with zero dependencies, hooks, render props and context helpers, tested across three React versions by rewriting the resolution at install time, with a release line that stopped in March 2020 and commits that have continued on a differently named default branch ever since.
Who is it for?
Adopt react-async if you want one data-loading abstraction across render props, context and hooks, because the zero-dependency claim means it will not drag anything into your bundle and the metadata it exposes, pending state, start and finish times, cancel and reload, covers the states a hand-rolled loader usually forgets.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The release line stopped in 2020, the branch did not

Get the dates first, because they change what the repository is. The three most recent releases are 10.0.0 from December 2019, a prerelease of the same version from the same day, and 10.0.1 from March 2020 with a title about TypeScript fixes. So the last tagged release is more than six years old. Now the other half: the repository is not archived, the last push was on 2026-09-28, and the default branch is not master and not main. It is a branch named for what comes next. So the pattern is a project that shipped a major version with a TypeScript rewrite in late 2019, fixed the types in early 2020, and has been working on a future version on a separate branch ever since without tagging a release. For a user this creates a specific and confusing situation. The documentation site is live and describes features you can see in the default branch, the package you install from the registry is the 2020 build, and nothing in the readme tells you which is which. The one hint is the upgrade notice near the top, which is about version 9, so even that is two versions behind the newest tag. The practical approach is to install the published version, read the source on the default branch, and assume they are close but not identical. Anything in the feature list marked experimental, such as the Suspense support, is most likely present in the branch and absent or different in what you get from the registry.

Four ways to consume the same abstraction, and that is the actual design decision

The feature list offers render props, context-based helper components, and hooks, and the headline counts them as separate options. That is the right way to think about it, because the choice is not stylistic. Render props are the oldest interface and work in any React version, at the cost of nesting a function in your markup every time you load something. Context-based helpers give you a component that owns the loading and shares the result down a tree, which suits a page that has several consumers of one request. Hooks are the modern answer and the one most projects will pick. The installation path is a single package, and the readme is careful to frame the library as making no assumptions about the shape of your data or the type of request, and it names the data sources it works with, the built-in fetch, another HTTP client, or a GraphQL client. That neutrality is the design claim worth testing, because a data loader that assumes your data looks a particular way ends up being a data loader you have to work around. The state it exposes is also worth noting in detail, since this is the part people reimplement badly. You get pending and settled flags, start and finish timestamps, and two actions, cancel and reload. There is automatic re-running when a watched value changes, three callbacks for resolution, rejection and cancellation, an abort controller for cancelling the request itself, a setter for optimistic updates before the response arrives, and an initial value for server-side rendering.

Compatibility is tested by rewriting the resolution at install time

The most interesting thing in this repository is a group of test scripts, and they explain what the maintainers thought the hard part of this library was. The problem with a React library is not the code, it is that the code has to keep working when the host framework changes underneath it. The scripts here answer that by testing three points on the React version axis, and the mechanism is crude and effective. One script installs an old React version, rewrites the resolution entries in the manifest so the whole workspace resolves to that version, reinstalls, and runs the component tests. Another installs the next prerelease of React, does the same, and runs the full suite. A third installs the latest release, does the same, and runs the full suite. A fourth runs all three in sequence and is what the continuous integration entry point calls. The rewrite is done with a small script that reads the manifest, sets the resolutions to match whatever React version was just installed, and reinstalls. So the library is tested against the floor of its supported range, against the bleeding edge, and against the current release, in one job. The cost is visible too: the version range in the readme is stated as a very narrow set of browser targets, and the test scripts are written for a package manager workflow with a monorepo layout, so a contributor on a different setup has work to do before they can run anything.

Eleven example projects, and the example list is the feature matrix

The examples directory is worth reading as documentation, because the list is a table of the situations this library claims to handle and each one is a separate package. There is a basic example for the fetch API, one for the hook interface, and one for a custom instance, which is the case where you configure the loader once and share it. Then the integration cases, and this is where the list becomes informative. There is an example using the abort controller, one using a GraphQL client rather than a plain request, one with a server framework, one with a mobile runtime, one with a router, one with suspense, and one with TypeScript. Each of those is a claim that the abstraction does not assume a particular data source, a particular rendering environment or a particular build. The router example in particular is the one that matters most in practice, because a data loader that does not integrate with your router's loading states is a data loader you end up fighting during every navigation, and there is a documented guide for separating view from logic alongside it. The mobile example answers the question a library like this always gets, which is whether it depends on a browser. The suspense example is the one to read with care, because the feature list marks that support as experimental, and an example that works is not the same as an API that is stable.

Zero dependencies, and the tooling is where the weight is

One feature claim deserves a close look because it is the kind that ages badly in either direction. The library declares zero dependencies. That is a real constraint on its design, not a marketing line, and it explains several things you can see in the surface. It cannot wrap a data fetching library for you, which is why the readme names three different clients as things you can use. It cannot bring a state container, which is why there is a set of own state properties and actions instead. And it cannot provide an abort implementation, which is why the abort controller is something you supply. What that buys you is a dependency graph with nothing in it, and a bundle you can measure rather than estimate, which is why there is a bundle size badge in the header pointing at a service that reports the minified package size. That badge is the number to watch, because a library with no dependencies can still grow, and the growth will come from feature requests rather than from a version bump in something else. The tooling around it is heavier than the library, which is normal. The repository has a monorepo layout with a workspace field and a release tool, a component workshop, a codesandbox configuration, a documentation generator configuration, a changelog automation file, a migrations directory, a renovate file, and a static hosting configuration for the documentation. That is a lot of infrastructure, and it is also the reason the library can claim to be tested on three React versions at once.

Editorial conclusion

Adopt react-async if you want one data-loading abstraction across render props, context and hooks, because the zero-dependency claim means it will not drag anything into your bundle and the metadata it exposes, pending state, start and finish times, cancel and reload, covers the states a hand-rolled loader usually forgets. Do not adopt it on the assumption that the 2020 release line is what you are reading, because the last tagged release is 10.0.1 from 2020-03-27 while the default branch is not main and has been receiving commits since, so the code you inspect and the code you install are different artefacts. Two things to check before you commit. Read the compatibility scripts, because the test suite re-pins React to an old version, to the next prerelease, and to latest in three separate runs, which tells you the supported range is wide and tested but also that the last time somebody did it was 2020. And check whether the experimental Suspense path matters to you, because it is labelled experimental in the feature list and a data loader that straddles two React concurrency models is where a library like this ages badly.

Frequently asked questions

What is the latest react-async release?

v10.0.1, published on 2020-03-27, titled as TypeScript fixes, following v10.0.0 in December 2019 which was the native TypeScript release. The repository is not archived, the last push was on 2026-09-28, and the default branch is not main.

Does react-async have any dependencies?

None, according to the feature list. It works with the fetch API, other data fetching clients, and GraphQL clients, and it exposes its own state properties and actions rather than delegating to a state container.

What interfaces does react-async offer for consuming data?

Render props, context-based helper components, and the useAsync and useFetch hooks. The feature list also names an experimental Suspense mode and a devtools package for stepping through the loading sequence.

How does react-async test React version compatibility?

With scripts that install an older React, the next prerelease, and the latest release in turn, rewrite the resolution entries in the manifest to match, reinstall, and run the suite. A fourth script runs all three, and the continuous integration entry point calls it.

What can I do with react-async besides fetching?

It exposes pending state and start and finish timestamps, cancel and reload actions, automatic re-running on a watched value, callbacks for resolution, rejection and cancellation, an abort controller for the request, a setter for optimistic updates, and an initial value for server-side rendering.

Official sources

  1. async-library/react-async on GitHub
  2. License: ISC
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/async-library-react-async.svg)](https://hysenlabs.com/projects/async-library-react-async)