> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bloom.diy/llms.txt
> Use this file to discover all available pages before exploring further.

# App Structure

> Understand how your Bloom app is organized and what each file does.

Every Bloom app is a monorepo containing an Expo frontend and a Convex backend. This architecture gives you a cross-platform mobile app (iOS, Android, and web) with a real-time serverless backend, all in one codebase.

## Directory Overview

```
your-app/
├── .env                        # Environment variables
├── package.json                # Workspace configuration
├── turbo.json                  # Task runner configuration
│
├── apps/
│   └── default/                # Expo app (iOS, Android, Web)
│       ├── app/                # App screens and layouts
│       │   ├── _layout.tsx     # Root layout with providers
│       │   └── index.tsx       # Main entry screen
│       ├── lib/                # Shared utilities
│       │   └── auth-client.ts  # Authentication client
│       ├── app.json            # Expo configuration
│       └── package.json        # App dependencies
│
└── packages/
    └── backend/                # Convex backend
        └── convex/
            ├── schema.ts       # Database schema
            ├── functions.ts    # Auth wrapper functions
            ├── auth.ts         # Authentication setup
            ├── http.ts         # HTTP endpoints
            └── _generated/     # Auto-generated types
```

## Root Files

The root of your project contains configuration files that tie everything together.

<AccordionGroup>
  <Accordion title="package.json" icon="box">
    Defines your monorepo workspace structure using Bun workspaces. It includes scripts to run your app and backend together.

    ```json theme={null}
    {
      "workspaces": ["apps/*", "packages/*"],
      "scripts": {
        "dev": "turbo dev",
        "dev:backend": "turbo dev --filter=@bloom/backend",
        "dev:mobile": "turbo dev --filter=@bloom/mobile"
      }
    }
    ```

    Run `bun run dev` to start both the frontend and backend simultaneously.
  </Accordion>

  <Accordion title="turbo.json" icon="gauge-high">
    Configures Turborepo, which orchestrates tasks across your monorepo. It defines how `dev`, `build`, `lint`, and `typecheck` commands run across packages.
  </Accordion>

  <Accordion title=".env" icon="key">
    Stores environment variables shared across your app. Required variables:

    * `CONVEX_DEPLOYMENT` — Your Convex deployment identifier
    * `EXPO_PUBLIC_CONVEX_URL` — The Convex cloud URL for your app
    * `EXPO_PUBLIC_CONVEX_SITE_URL` — The URL for Convex HTTP actions (used for auth)

    <Warning>
      Never commit `.env` files to version control. Use `.env.example` as a template.
    </Warning>
  </Accordion>
</AccordionGroup>

## Frontend: `apps/default/`

Your Expo app lives here. It's a universal React Native app that runs on iOS, Android, and web from a single codebase.

### App Directory

The `app/` folder uses Expo Router for file-based routing. Each file becomes a route.

<Tabs>
  <Tab title="_layout.tsx">
    The root layout wraps your entire app with required providers:

    ```tsx theme={null}
    export default function RootLayout() {
      return (
        <ConvexProvider client={convex}>
          <ConvexBetterAuthProvider client={authClient}>
            <Stack screenOptions={{ headerShown: false }} />
          </ConvexBetterAuthProvider>
        </ConvexProvider>
      );
    }
    ```

    * **ConvexProvider** — Connects your app to the Convex backend
    * **ConvexBetterAuthProvider** — Manages authentication state
    * **Stack** — The navigation container for your screens
  </Tab>

  <Tab title="index.tsx">
    The main entry screen of your app. This is what users see when they open your app. By default, it's a blank screen ready for you to build on.

    Add new screens by creating files in this directory. For example, `profile.tsx` becomes the `/profile` route.
  </Tab>
</Tabs>

### Key Configuration Files

<AccordionGroup>
  <Accordion title="app.json" icon="gear">
    Expo configuration file that defines your app's name, icons, splash screen, and platform-specific settings.

    ```json theme={null}
    {
      "expo": {
        "name": "Your App Name",
        "slug": "your-app",
        "newArchEnabled": true,
        "plugins": [
          "expo-router",
          "expo-splash-screen",
          "expo-secure-store"
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="lib/auth-client.ts" icon="user-shield">
    Configures the Better Auth client for authentication. Handles platform-specific storage (secure store on native, cookies on web) and cross-domain authentication.

    ```tsx theme={null}
    export const authClient = createAuthClient({
      baseURL: process.env.EXPO_PUBLIC_CONVEX_SITE_URL,
      plugins: [
        expoClient({
          storage: expoSecureStore,
        }),
        crossDomainClient(),
      ],
    });
    ```
  </Accordion>

  <Accordion title="tsconfig.json" icon="code">
    TypeScript configuration with path aliases for cleaner imports:

    * `@/*` — Maps to the current directory
    * `@/convex/*` — Maps to `../../packages/backend/convex/*`

    This lets you import backend types directly:

    ```tsx theme={null}
    import { api } from "@/convex/_generated/api";
    ```
  </Accordion>
</AccordionGroup>

## Backend: `packages/backend/convex/`

Your Convex backend contains your database schema, serverless functions, and authentication logic.

### Core Files

<Tabs>
  <Tab title="schema.ts">
    Defines your database tables and their structure. Convex uses this to generate type-safe queries.

    ```ts theme={null}
    import { defineSchema, defineTable } from "convex/server";
    import { v } from "convex/values";

    export default defineSchema({
      posts: defineTable({
        title: v.string(),
        content: v.string(),
        authorId: v.string(),
      }),
    });
    ```

    Changes to your schema automatically sync with your database.
  </Tab>

  <Tab title="functions.ts">
    Provides authentication-aware wrapper functions for your queries, mutations, and actions:

    * `authQuery` — Query that requires the user to be logged in
    * `authMutation` — Mutation that requires the user to be logged in
    * `authAction` — Action that requires the user to be logged in

    ```ts theme={null}
    import { authQuery } from "./functions";

    export const getMyPosts = authQuery({
      handler: async (ctx) => {
        const userId = ctx.session.user.id;
        return await ctx.db
          .query("posts")
          .filter((q) => q.eq(q.field("authorId"), userId))
          .collect();
      },
    });
    ```
  </Tab>

  <Tab title="auth.ts">
    Configures Better Auth with Convex integration. Sets up OAuth providers (Google, GitHub, Apple) and authentication plugins.

    The default setup includes:

    * Google OAuth (enabled by default)
    * Email/password authentication
    * Anonymous authentication
    * Expo-specific session handling
  </Tab>

  <Tab title="http.ts">
    Sets up HTTP endpoints for authentication. This routes auth requests (sign in, sign out, OAuth callbacks) to the Better Auth handler.

    ```ts theme={null}
    const http = httpRouter();

    auth.registerRoutes(http, {
      allowedOrigins: ["*"],
    });

    export default http;
    ```
  </Tab>
</Tabs>

### Generated Files

The `_generated/` folder contains auto-generated TypeScript types. These are created by Convex and should not be edited manually.

| File             | Purpose                                     |
| ---------------- | ------------------------------------------- |
| `api.d.ts`       | Type-safe references to your functions      |
| `dataModel.d.ts` | Types matching your database schema         |
| `server.d.ts`    | Server-side types for queries and mutations |

<Note>
  These files update automatically when you modify your schema or functions. They enable full type safety between your frontend and backend.
</Note>

## Key Patterns

### Environment Variables

Environment variables flow through your app in a specific way:

1. Defined in `.env` at the project root
2. Backend reads them via the `--env-file` flag
3. Frontend loads them through Metro bundler using `@expo/env`
4. Variables prefixed with `EXPO_PUBLIC_` are available in frontend code

### Type-Safe Imports

The path alias `@/convex/*` lets your frontend import backend types directly:

```tsx theme={null}
import { api } from "@/convex/_generated/api";
import { useQuery } from "convex/react";

function PostList() {
  const posts = useQuery(api.posts.list);
  // posts is fully typed based on your schema
}
```

### Authentication Flow

Authentication is pre-wired between frontend and backend:

1. Frontend uses `authClient` from `lib/auth-client.ts`
2. Auth requests route through Convex HTTP endpoints
3. Session state syncs via `ConvexBetterAuthProvider`
4. Backend functions access the user via `ctx.session`

## What's Next?

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    Learn how to configure OAuth providers
  </Card>

  <Card title="Backend Dashboard" icon="chart-line" href="/backend-dashboard">
    Monitor your database and functions
  </Card>
</CardGroup>
