mrkeyoor.com_
Wed 05 Aug 05:02 UTC
npmInfraupdated 05 Aug 2026

firebase

firebase is the official client SDK for Google's Firebase platform: one npm package that wraps 20+ scoped @firebase/* modules covering Auth, Firestore, Realtime Database, Cloud Storage, Cloud Functions calls, Analytics, Messaging, Remote Config, App Check, and the newer AI and Data Connect products. You wire your web or Node app straight to Google-hosted backends: users sign in, documents sync in realtime, files upload, all without writing a server. Since v9 the API is modular (import individual functions) so bundlers can tree-shake the services you do not use. It is the client half of a platform; the services themselves live in your Firebase project on Google Cloud.

Verdict

Unbeatable time-to-first-feature for realtime, mobile-plus-web apps, and the SDK itself is actively maintained by Google. Go in with eyes open: you are marrying a proprietary platform, and the document model plus per-read billing punish schema mistakes later.

API stability4/5The v9 modular API has held stable through v10, v11, and v12; majors arrive roughly yearly but breaking changes are mostly runtime support and deprecated-surface removals, and compat shims eased the big v8-to-v9 rewrite.
Docs4/5firebase.google.com has extensive guides, API references, and codelabs for every product, but content is split across products and versions, and the pre-v9 namespaced examples still circulating in the wider web mislead newcomers.
Maintenance5/5Google ships releases near-weekly (12.17.0 current, pushed Aug 2026), with a public roadmap of new products like Data Connect and AI; 727 open issues and PRs is proportionate to a monorepo of 28 packages.
Ecosystem4/5First-party coverage is enormous (iOS, Android, Flutter, admin SDKs, emulator suite) and frameworks have bindings like reactfire and angularfire, but the third-party ecosystem orbits Google's platform rather than extending the JS SDK itself.

Use it if

  • You want auth, a realtime database, file storage, and hosted functions without building or operating any backend, and shipping fast matters more than infrastructure control
  • You need realtime sync across clients with offline persistence; Firestore's onSnapshot listeners and local cache are genuinely hard to replicate yourself
  • You are on mobile plus web; the same Firebase project serves iOS, Android, and JS SDKs with one auth and data layer
  • Your usage fits the free Spark tier or predictable low volume, where the managed platform is effectively free
Skip it if

Setup reality

npm install firebase, then paste the config object from the Firebase console into initializeApp. Every service needs console-side setup first: enable each sign-in provider by hand, create the Firestore database and pick a region you can never change, write security rules in Google's own rules language (the default locked mode makes every request fail until you do). The v9+ modular API means long import lists from firebase/auth and firebase/firestore, and most Stack Overflow answers still show the pre-v9 namespaced style, so half the snippets you find need translating. Local development against the Emulator Suite requires installing firebase-tools separately and a Java runtime. SSR frameworks need care: Analytics and Messaging are browser-only and crash when imported in Node.

Patterns

Initialize the app onceinit-app

import { initializeApp } from 'firebase/app'

const app = initializeApp({
  apiKey: '...',
  authDomain: 'my-app.firebaseapp.com',
  projectId: 'my-app',
  storageBucket: 'my-app.appspot.com',
  appId: '...'
})

The apiKey is a project identifier, not a secret; access control lives in security rules, which start locked and deny everything.

Email/password sign-inemail-sign-in

import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'

const auth = getAuth(app)
const cred = await signInWithEmailAndPassword(auth, email, password)
console.log(cred.user.uid)

Fails with auth/operation-not-allowed until you enable the Email/Password provider in the console's Authentication tab.

React to sign-in state changesauth-state

import { getAuth, onAuthStateChanged } from 'firebase/auth'

const unsubscribe = onAuthStateChanged(getAuth(app), (user) => {
  if (user) showApp(user)
  else showLogin()
})

Auth state restores asynchronously on page load, so currentUser is null at startup even for signed-in users; always wait for this callback.

Create or overwrite a documentfirestore-write

import { getFirestore, doc, setDoc, collection, addDoc } from 'firebase/firestore'

const db = getFirestore(app)
await setDoc(doc(db, 'users', uid), { name: 'Ada', plan: 'free' })
const ref = await addDoc(collection(db, 'posts'), { title: 'Hi', ts: Date.now() })

setDoc replaces the whole document; pass { merge: true } or use updateDoc to change individual fields.

Read a single documentfirestore-read

import { doc, getDoc } from 'firebase/firestore'

const snap = await getDoc(doc(db, 'users', uid))
if (snap.exists()) {
  console.log(snap.data())
}

A missing document is not an error; getDoc resolves normally and exists() is false, so check it before calling data().

Query a collection with filtersfirestore-query

import { collection, query, where, orderBy, limit, getDocs } from 'firebase/firestore'

const q = query(
  collection(db, 'posts'),
  where('authorId', '==', uid),
  orderBy('ts', 'desc'),
  limit(20)
)
const snap = await getDocs(q)
snap.forEach((d) => console.log(d.id, d.data()))

Combining where and orderBy on different fields needs a composite index; the thrown error includes a console link that creates it for you.

Subscribe to live document updatesrealtime-listener

import { doc, onSnapshot } from 'firebase/firestore'

const unsubscribe = onSnapshot(doc(db, 'games', gameId), (snap) => {
  render(snap.data())
})
// later: unsubscribe()

Every listener re-read bills as document reads; forgetting to unsubscribe in SPA route changes leaks listeners and money.

Upload a file and get its URLstorage-upload

import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage'

const storage = getStorage(app)
const fileRef = ref(storage, `avatars/${uid}.png`)
await uploadBytes(fileRef, file)
const url = await getDownloadURL(fileRef)

Storage has its own security rules separate from Firestore's; default rules block uploads from unauthenticated users.

Call a Cloud Functioncallable-function

import { getFunctions, httpsCallable } from 'firebase/functions'

const functions = getFunctions(app)
const createInvite = httpsCallable(functions, 'createInvite')
const { data } = await createInvite({ email: 'x@y.com' })

Callables pass auth context automatically; if your function is deployed outside us-central1, pass the region to getFunctions or you get 404s.

Develop against the local Emulator Suitelocal-emulators

import { connectAuthEmulator } from 'firebase/auth'
import { connectFirestoreEmulator } from 'firebase/firestore'

if (location.hostname === 'localhost') {
  connectAuthEmulator(auth, 'http://127.0.0.1:9099')
  connectFirestoreEmulator(db, '127.0.0.1', 8080)
}

Emulators come from the separate firebase-tools CLI and need Java installed; connect calls must run before any other SDK operation.

Enable offline cache for Firestoreoffline-persistence

import { initializeFirestore, persistentLocalCache, persistentMultipleTabManager } from 'firebase/firestore'

const db = initializeFirestore(app, {
  localCache: persistentLocalCache({
    tabManager: persistentMultipleTabManager()
  })
})

Use initializeFirestore instead of getFirestore when configuring the cache; the older enableIndexedDbPersistence API is deprecated.

Write a trustworthy server-side timestampserver-timestamp

import { doc, updateDoc, serverTimestamp } from 'firebase/firestore'

await updateDoc(doc(db, 'posts', id), {
  updatedAt: serverTimestamp()
})

Client clocks lie; in latency-compensated local snapshots the field is briefly null before the server value arrives.

Alternatives

PackageRegistryPick it when
@supabase/supabase-jsnpmYou want the same auth-plus-data-plus-realtime bundle on Postgres with an open-source, portable core
aws-amplifynpmYour organization is on AWS and you need Cognito, AppSync, and S3 as the managed backend
pocketbasenpmYou want a small self-hosted backend (auth, realtime, files) in a single binary with a JS client