Library / SDK
FirebaseExtended/reactfire avatar
FirebaseExtended/reactfire

ReactFire: Firebase hooks for web React, with Suspense kept optional

Hooks, Context Providers, and Components that make it easy to interact with Firebase.

3,570 stars403 forksTypeScriptMIT

At a glance

What is it?
ReactFire wraps the Firebase Web SDK in hooks and context providers so components can subscribe to auth state and Firestore documents without manual teardown. It targets web React only, and the project labels itself experimental.
Who is it for?
Adopt ReactFire if you are building a web React app on the Firebase Web SDK and want subscriptions tied to component lifetimes; the hooks unsubscribe on unmount and the providers keep SDK initialisation in one place. Do not adopt it for React Native or Expo, where the README points to react-native-firebase instead, and do not treat it as a supported Firebase product: the repository states it is maintained by Googlers on a best-effort basis and labelled experimental.
Can I use it commercially?
Yes. MIT 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 9 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

Editorial analysis

What ReactFire solves for web React apps on Firebase

The Firebase Web SDK is imperative. You attach a listener, hold the unsubscribe function, and remember to call it when the component goes away. ReactFire's README frames the pitch around exactly that: hooks such as `useUser` and `useFirestoreCollection` subscribe to auth state and realtime data, and "automatically unsubscribe when your component unmounts." That is the core value, and it is a small one but a real one, because the teardown bookkeeping is where most Firebase plus React bugs come from.

The second problem is access. Instead of importing the Firestore SDK directly at the top of a component file, you pull the instance out of context with `useFirestore`, or Remote Config with `useRemoteConfig`. The third problem is ordering. Firestore and Remote Config require settings like `enablePersistence` to be applied before any data fetch happens, which is awkward in a world of re-renders. ReactFire answers with `useInitFirestore` and `useInitRemoteConfig`, which the README says "guarantee they're set before anything else."

The audience is narrow and clearly stated: web React apps that already use the Firebase Web SDK. The README is explicit that ReactFire is "not compatible with React Native or Expo" and directs those projects to react-native-firebase. If you are not on the web, this library is not for you.

How the provider and hook layers fit together

The architecture visible in the example is two layers. `FirebaseAppProvider` sits at the root and takes your `firebaseConfig` object. Below it, per-service providers such as `FirestoreProvider` receive an SDK instance, which the example obtains with `getFirestore(useFirebaseApp())`. Hooks then read from those contexts: `useFirestore()` returns the instance, and `useFirestoreDocData(ref)` subscribes to a document reference and returns a `{ status, data }` pair.

That status field is the default contract. Every async hook reports `loading` while the first value is in flight, and the example branches on it before reading `data`. The repository layout backs this up: `src/` holds the implementation, `test/` has per-service suites, and the npm scripts split testing by product, with `test:firestore`, `test:database`, `test:auth`, `test:functions` and `test:storage` each running the Firebase emulators with `--only` for that product. That is a meaningful signal about how the maintainers verify behaviour: against emulators, per service, not against a live project.

Suspense is a second, parallel path through the same hooks. When enabled, hooks throw promises that React's `<Suspense>` boundary catches, so you stop checking `status` yourself. The README is careful to say this is off by default and opted into with a prop.

Installing ReactFire and rendering a first subscribed component

ReactFire ships as a normal npm package alongside the Firebase SDK, which is a peer dependency. The README gives both package managers:

bash
npm install --save firebase reactfire

or with yarn:

bash
yarn add firebase reactfire

The README also warns that depending on your targeted platforms you may need polyfills, naming globalThis and Proxy as the most commonly needed. Node is pinned at `>=14` in the package manifest, and the peer dependency range for Firebase is `^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || next`, with React at `>=16 || experimental`.

The smallest working shape is a provider at the root, a service provider inside it, and a hook component. This is the README's own example, trimmed to the essentials:

jsx
import { doc, getFirestore } from 'firebase/firestore';
import { FirebaseAppProvider, FirestoreProvider, useFirestoreDocData, useFirestore, useFirebaseApp } from 'reactfire';

function BurritoTaste() {
  const burritoRef = doc(useFirestore(), 'tryreactfire', 'burrito');
  const { status, data } = useFirestoreDocData(burritoRef);
  if (status === 'loading') return <p>Fetching burrito flavor...</p>;
  return <p>The burrito is {data.yummy ? 'good' : 'bad'}!</p>;
}

What you should see: the component renders the loading paragraph first, then swaps to the data paragraph once the document arrives, and keeps updating as the document changes. No unsubscribe call appears anywhere, because the hook handles it.

To switch to Suspense, the README's change is a single prop on the root provider:

jsx
<FirebaseAppProvider firebaseConfig={firebaseConfig} suspense={true}>

With that set, the same hook throws instead of returning `loading`, and a `<Suspense>` boundary above it renders your fallback. The README points to `example/withSuspense` and `example/withoutSuspense` for full samples, and a live StackBlitz fork is linked from the README.

SuspenseWithPerf and what the optional Suspense mode costs you

`<SuspenseWithPerf />` is the same Suspense behaviour plus timing: the README says it measures how long the fallback was shown using the browser's User Timing API. That is a narrow feature, and it is the only performance instrumentation the README describes. There is no claim about hook overhead, re-render counts or bundle cost in the README, so treat any such comparison you read elsewhere as unverified.

The cost of opting into Suspense is that your error and loading handling moves out of the component and into boundaries you place yourself. The default mode keeps `status` in the hook result, which is more verbose but keeps the branch local and easy to reason about. Neither is wrong; the default is the safer starting point because it does not require you to restructure the tree.

One thing the README does not document is what happens to a throwing hook when no Suspense boundary exists above it. That failure mode is on you to avoid, and it is the main reason to leave `suspense` off until you have boundaries in place.

Where ReactFire is the wrong tool

The first limit is platform. React Native and Expo are out, per the README, and the recommended replacement is react-native-firebase. If you are shipping a mobile app, stop here.

The second limit is support expectations. The repository carries a Status: Experimental badge and states that it "is maintained by Googlers but is not a supported Firebase product," with issues answered by maintainers and community members "on a best-effort basis." That is a governance statement, not a bug, but it should shape how much of your data layer you are willing to route through it. Note also that one recent release, v4.2.4, is marked DEPRECATED in the release list, so pinning to the newest tag without reading release notes is a poor habit here.

The third limit is scope. ReactFire is a thin binding over the Firebase Web SDK. It does not abstract Firebase away, it does not give you a query cache, and it does not manage server state beyond what the SDK already streams. If your problem is caching, deduplication or optimistic updates across many data sources, a data-fetching library is the layer you want, and ReactFire will not replace it. The repository does not document any rollback procedure for a bad upgrade, so plan your version pinning before you take a major bump.

ReactFire versus plain Firebase calls in React

The honest alternative is not another library. It is writing the `onSnapshot` call yourself inside a `useEffect`, keeping the returned unsubscribe function in a ref, and calling it in the cleanup. That is what ReactFire does for you, and for a single document subscription the difference is a dozen lines.

The difference in approach shows up as your app grows. With hand-written effects, every component repeats the same subscribe, set-state, unsubscribe pattern, and each one is a place to leak a listener. With ReactFire, the subscription lifecycle is uniform and the SDK instances come from context rather than module-level imports, which matters when you want to swap or test an instance. The trade is a dependency plus a provider tree you must set up correctly, and the ordering hooks (`useInitFirestore`, `useInitRemoteConfig`) exist precisely because getting initialisation order wrong is easy.

If you already have a working patterns file for Firebase subscriptions and a small number of them, hand-rolling is defensible. If you have many components reading realtime data, the uniform lifecycle is the reason to take the dependency.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-22. The most recent release listed is v4.2.6 from 2026-07-24, preceded by v4.2.5 and by v4.2.4, which carries a DEPRECATED marker. Release cadence in that window is patch-level, which suggests fixes rather than new surface area.

The licence is MIT, declared both in the repository metadata and in the package manifest. That permits commercial use and modification under the usual MIT terms; it says nothing about support obligations, and the README's best-effort statement is the practical answer on that front. This is not legal advice, and if your organisation has licence review requirements, run the MIT text through it.

Upgrade cost is concentrated in major versions. The docs directory ships an upgrade guide specifically for v3 to v4, which tells you the maintainers treat major bumps as breaking. Because the package is published with `dist` and `src` in its `files` list, you can read the shipped source when a hook behaves unexpectedly instead of guessing from types.

Editorial conclusion

Adopt ReactFire if you are building a web React app on the Firebase Web SDK and want subscriptions tied to component lifetimes; the hooks unsubscribe on unmount and the providers keep SDK initialisation in one place. Do not adopt it for React Native or Expo, where the README points to react-native-firebase instead, and do not treat it as a supported Firebase product: the repository states it is maintained by Googlers on a best-effort basis and labelled experimental. Verify two things before committing: that your React version satisfies the peer dependency (>=16 or experimental) and that your bundler target has globalThis and Proxy, since the README lists polyfills as a possible requirement. Then check the v3 to v4 upgrade guide if you are moving an existing codebase.

Frequently asked questions

What exactly is Firebase used for?

ReactFire itself does not answer this; it wraps the Firebase Web SDK. In this repository that means auth state, Firestore and Realtime Database data, Cloud Functions and Storage, each exposed through hooks and context providers such as useFirestore and useRemoteConfig.

Can I use React Native with Firebase?

Yes, but not with ReactFire. The README states ReactFire is designed for web React apps and is not compatible with React Native or Expo, and it directs React Native projects to react-native-firebase instead.

Is Firebase a backend?

The README treats Firebase as a set of SDKs that ReactFire wraps rather than describing a backend architecture. What the hooks touch are Firebase services: Firestore documents, auth state, Remote Config and the rest of the Web SDK.

Official sources

  1. FirebaseExtended/reactfire on GitHub
  2. License: MIT
  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/firebaseextended-reactfire.svg)](https://hysenlabs.com/projects/firebaseextended-reactfire)