Elegant, typed abstractions for Firestore. Write clean, strongly-typed code without boilerplate.
This repository consolidates what were previously three separate packages into a single monorepo. The original repositories (typed-firestore-server, typed-firestore-react, and typed-firestore-react-native) are now archived. The NPM packages and their names remain unchanged.
| Package | Description |
|---|---|
@typed-firestore/server |
Server environments (firebase-admin) |
@typed-firestore/react |
React applications (Firebase web SDK) |
@typed-firestore/react-native |
React Native (React Native Firebase) |
Firestore's API gives you DocumentData everywhere, leaving type safety up to
you. Typed Firestore fixes that with a simple idea: define your collection
types once, and let everything else flow from there.
- Non-intrusive API - No lock-in, just thin typed wrappers around the official SDKs
- Type your database once - Create typed collection refs and all functions infer the rest
- Mutable documents - Get back documents with typed
updateanddeletemethods attached - Typed select statements - Narrow both the data and its type simultaneously
- Transaction support - Simplified transaction code with typed document handles
- Collection processing - Iterate over entire collections with constant memory usage via automatic pagination
- Cloud function helpers - Get typed data from 2nd gen cloud function events
- Consistent across platforms - The same concepts and API patterns on server, web, and mobile
import { CollectionReference } from "firebase-admin/firestore";
import { db } from "./firestore";
import type { User, Book } from "./types";
export const refs = {
users: db.collection("users") as CollectionReference<User>,
books: db.collection("books") as CollectionReference<Book>,
} as const;Server:
import { getDocument, getDocuments } from "@typed-firestore/server";
const user = await getDocument(refs.users, userId);
await user.update({ is_active: true });
const books = await getDocuments(refs.books, (query) =>
query.where("is_published", "==", true).limit(50),
);React:
import { useDocument } from "@typed-firestore/react";
function UserProfile({ userId }: { userId: string }) {
const [user, isLoading] = useDocument(refs.users, userId);
if (isLoading) return <Spinner />;
return <div>{user.data.displayName}</div>;
}React Native:
import { useDocument } from "@typed-firestore/react-native";
// Same API as the React package, but backed by React Native Firebase
const [user, isLoading] = useDocument(refs.users, userId);Detailed documentation for each package can be found in their respective README files:
There is also an in-depth article explaining the motivation and design behind this library.
Install only the package you need:
# Server (firebase-admin)
pnpm add @typed-firestore/server
# React (Firebase web SDK)
pnpm add @typed-firestore/react
# React Native (React Native Firebase)
pnpm add @typed-firestore/react-native