diff --git a/packages/react/README.md b/packages/react/README.md
index e69de29b..dd592f1a 100644
--- a/packages/react/README.md
+++ b/packages/react/README.md
@@ -0,0 +1,406 @@
+# @tanstack-query-firebase/react
+
+TanStack Query hooks for Firebase and React.
+
+## Installation
+
+```bash
+npm install @tanstack-query-firebase/react
+# or
+yarn add @tanstack-query-firebase/react
+# or
+pnpm add @tanstack-query-firebase/react
+```
+
+### Peer Dependencies
+
+This package requires the following peer dependencies:
+
+```json
+{
+ "@tanstack/react-query": "^5",
+ "firebase": "^11.3.0"
+}
+```
+
+## Setup
+
+1. Initialize Firebase in your application:
+
+```typescript
+import { initializeApp } from 'firebase/app';
+import { getAuth } from 'firebase/auth';
+import { getFirestore } from 'firebase/firestore';
+
+const app = initializeApp({
+ // your firebase config
+});
+
+export const auth = getAuth(app);
+export const firestore = getFirestore(app);
+```
+
+2. Set up TanStack Query:
+
+```typescript
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: false,
+ staleTime: 5 * 60 * 1000, // 5 minutes
+ },
+ mutations: {
+ retry: false
+ },
+ },
+});
+
+function App() {
+ return (
+
+ {/* Your app components */}
+
+ );
+}
+```
+
+## Usage
+
+### Authentication
+
+```typescript
+import {
+ useSignInWithEmailAndPasswordMutation,
+ useSignOutMutation,
+ useCreateUserWithEmailAndPasswordMutation
+} from '@tanstack-query-firebase/react/auth';
+import { auth } from './firebase-config';
+
+function AuthComponent() {
+ const signInMutation = useSignInWithEmailAndPasswordMutation(auth);
+ const signOutMutation = useSignOutMutation(auth);
+ const createUserMutation = useCreateUserWithEmailAndPasswordMutation(auth);
+
+ const handleSignIn = () => {
+ signInMutation.mutate({
+ email: 'user@example.com',
+ password: 'password123'
+ });
+ };
+
+ const handleSignUp = () => {
+ createUserMutation.mutate({
+ email: 'newuser@example.com',
+ password: 'password123'
+ });
+ };
+
+ const handleSignOut = () => {
+ signOutMutation.mutate();
+ };
+
+ return (
+
+ {signInMutation.isSuccess && (
+
Signed in as: {signInMutation.data.user.email}
+ )}
+
+
+
+
+ );
+}
+```
+
+### Firestore Queries
+
+```typescript
+import { useDocumentQuery, useCollectionQuery } from '@tanstack-query-firebase/react/firestore';
+import { doc, collection, query, where } from 'firebase/firestore';
+import { firestore } from './firebase-config';
+
+// Document Query
+function UserProfile({ userId }: { userId: string }) {
+ const userDoc = doc(firestore, 'users', userId);
+
+ const { data, isPending, isError } = useDocumentQuery(userDoc, {
+ queryKey: ['user', userId],
+ });
+
+ if (isPending) return Loading...
;
+ if (isError) return Error loading user
;
+
+ if (data?.exists()) {
+ const userData = data.data();
+ return Name: {userData.name}
;
+ }
+
+ return User not found
;
+}
+
+// Collection Query
+function UsersList() {
+ const usersCollection = collection(firestore, 'users');
+ const activeUsersQuery = query(usersCollection, where('active', '==', true));
+
+ const { data, isPending } = useCollectionQuery(activeUsersQuery, {
+ queryKey: ['users', 'active'],
+ });
+
+ if (isPending) return Loading users...
;
+
+ return (
+
+ {data?.docs.map(doc => (
+ - {doc.data().name}
+ ))}
+
+ );
+}
+```
+
+### Firestore Mutations
+
+```typescript
+import {
+ useSetDocumentMutation,
+ useUpdateDocumentMutation,
+ useDeleteDocumentMutation,
+ useAddDocumentMutation
+} from '@tanstack-query-firebase/react/firestore';
+import { doc, collection } from 'firebase/firestore';
+import { firestore } from './firebase-config';
+
+function UserEditor({ userId }: { userId: string }) {
+ const userDoc = doc(firestore, 'users', userId);
+ const usersCollection = collection(firestore, 'users');
+
+ const setMutation = useSetDocumentMutation(userDoc);
+ const updateMutation = useUpdateDocumentMutation(userDoc);
+ const deleteMutation = useDeleteDocumentMutation(userDoc);
+ const addMutation = useAddDocumentMutation(usersCollection);
+
+ const handleCreate = () => {
+ addMutation.mutate({
+ name: 'New User',
+ email: 'newuser@example.com',
+ createdAt: new Date()
+ });
+ };
+
+ const handleUpdate = () => {
+ updateMutation.mutate({
+ name: 'Updated Name',
+ updatedAt: new Date()
+ });
+ };
+
+ const handleDelete = () => {
+ deleteMutation.mutate();
+ };
+
+ return (
+
+
+
+
+
+ );
+}
+```
+
+### Data Connect
+
+```typescript
+import { useDataConnectQuery, useDataConnectMutation } from '@tanstack-query-firebase/react/data-connect';
+import { listMoviesRef, createMovieRef } from './dataconnect-generated';
+
+function MoviesApp() {
+ // Query
+ const { data, isPending, dataConnectResult } = useDataConnectQuery(
+ listMoviesRef()
+ );
+
+ // Mutation
+ const createMovieMutation = useDataConnectMutation(
+ (title: string) => createMovieRef({ title })
+ );
+
+ const handleCreateMovie = () => {
+ createMovieMutation.mutate('New Movie Title');
+ };
+
+ if (isPending) return Loading movies...
;
+
+ return (
+
+
Movies
+
+ {data?.movies.map(movie => (
+ - {movie.title}
+ ))}
+
+
+
Source: {dataConnectResult?.source}
+
+ );
+}
+```
+
+## Available Hooks
+
+### Authentication
+- `useApplyActionCodeMutation`
+- `useCheckActionCodeMutation`
+- `useConfirmPasswordResetMutation`
+- `useCreateUserWithEmailAndPasswordMutation`
+- `useDeleteUserMutation`
+- `useGetRedirectResultQuery`
+- `useReloadMutation`
+- `useRevokeAccessTokenMutation`
+- `useSendSignInLinkToEmailMutation`
+- `useSignInAnonymouslyMutation`
+- `useSignInWithCredentialMutation`
+- `useSignInWithEmailAndPasswordMutation`
+- `useSignOutMutation`
+- `useUpdateCurrentUserMutation`
+- `useVerifyPasswordResetCodeMutation`
+
+### Firestore
+- `useAddDocumentMutation`
+- `useClearIndexedDbPersistenceMutation`
+- `useCollectionQuery`
+- `useDeleteDocumentMutation`
+- `useDisableNetworkMutation`
+- `useDocumentQuery`
+- `useEnableNetworkMutation`
+- `useGetAggregateFromServerQuery`
+- `useGetCountFromServerQuery`
+- `useNamedQuery`
+- `useRunTransactionMutation`
+- `useSetDocumentMutation`
+- `useUpdateDocumentMutation`
+- `useWaitForPendingWritesQuery`
+- `useWriteBatchCommitMutation`
+
+### Data Connect
+- `useDataConnectQuery`
+- `useDataConnectMutation`
+- `DataConnectQueryClient`
+
+## Advanced Usage
+
+### Custom Query Options
+
+All hooks accept TanStack Query options:
+
+```typescript
+const { data } = useDocumentQuery(docRef, {
+ queryKey: ['custom', 'key'],
+ staleTime: 10 * 60 * 1000, // 10 minutes
+ gcTime: 30 * 60 * 1000, // 30 minutes
+ enabled: !!userId, // Conditional fetching
+});
+```
+
+### Firestore Source Options
+
+Specify where Firestore should fetch data:
+
+```typescript
+const { data } = useDocumentQuery(docRef, {
+ firestore: {
+ source: 'server' // 'default' | 'server' | 'cache'
+ }
+});
+```
+
+### Optimistic Updates
+
+```typescript
+const queryClient = useQueryClient();
+const updateMutation = useUpdateDocumentMutation(docRef);
+
+updateMutation.mutate(
+ { name: 'New Name' },
+ {
+ onMutate: async (newData) => {
+ await queryClient.cancelQueries({ queryKey: ['doc', docRef.id] });
+
+ const previousData = queryClient.getQueryData(['doc', docRef.id]);
+
+ queryClient.setQueryData(['doc', docRef.id], old => ({
+ ...old,
+ ...newData
+ }));
+
+ return { previousData };
+ },
+ onError: (err, variables, context) => {
+ queryClient.setQueryData(['doc', docRef.id], context?.previousData);
+ },
+ onSettled: () => {
+ queryClient.invalidateQueries({ queryKey: ['doc', docRef.id] });
+ }
+ }
+);
+```
+
+## TypeScript
+
+This package is written in TypeScript and provides full type safety:
+
+```typescript
+import { DocumentData, QueryDocumentSnapshot } from 'firebase/firestore';
+
+interface User extends DocumentData {
+ name: string;
+ email: string;
+ role: 'admin' | 'user';
+}
+
+const userDoc = doc(firestore, 'users', 'userId').withConverter({
+ toFirestore: (user: User) => user,
+ fromFirestore: (snapshot: QueryDocumentSnapshot) => snapshot.data() as User,
+});
+
+const { data } = useDocumentQuery(userDoc);
+// data is typed as DocumentSnapshot
+```
+
+## Error Handling
+
+All mutations include typed Firebase errors:
+
+```typescript
+const mutation = useSignInWithEmailAndPasswordMutation(auth);
+
+if (mutation.isError) {
+ const error = mutation.error;
+
+ switch (error.code) {
+ case 'auth/user-not-found':
+ console.log('User not found');
+ break;
+ case 'auth/wrong-password':
+ console.log('Invalid password');
+ break;
+ default:
+ console.log('An error occurred:', error.message);
+ }
+}
+```
+
+## License
+
+MIT
\ No newline at end of file