Skip to main content

Overview

Your Bible is built with TanStack Start, a full-stack React framework. The project follows a modular structure with clear separation of concerns.
your-bible/
├── convex/              # Convex backend configuration
├── src/                 # Source code
├── public/              # Static assets
├── .env.example         # Environment variable template
├── package.json         # Dependencies and scripts
├── tsconfig.json        # TypeScript configuration
├── vite.config.ts       # Vite build configuration
└── drizzle.config.ts    # Drizzle ORM configuration

Root Directory Files

package.json
file
Project metadata, dependencies, and npm scripts.Key Dependencies:
  • @tanstack/react-start - Full-stack React framework
  • convex - Real-time backend and database
  • better-auth - Authentication solution
  • drizzle-orm - Type-safe database queries
  • @google/genai - Google Gemini AI integration
  • platejs - Rich text editor
  • tailwindcss - Utility-first CSS framework
tsconfig.json
file
TypeScript compiler configuration with path aliases:
  • @/*./src/*
  • Strict type checking enabled
  • React 19 JSX transform
vite.config.ts
file
Vite build configuration:
  • TanStack Start plugin
  • Path resolution
  • Development server settings
  • Build optimizations
drizzle.config.ts
file
Drizzle ORM configuration:
  • Database connection
  • Migration settings
  • Schema location
.env.example
file
Template for environment variables. Copy to .env and fill in your values. See Environment Variables for details.

Source Directory (src/)

Main Entry Points

src/
├── app.tsx              # Root application component
├── routes.ts            # Route configuration
└── router.tsx           # Router setup
app.tsx
file
The root React component that:
  • Sets up providers (Query, Convex, Theme)
  • Configures global layout
  • Initializes authentication
  • Includes Toast notifications

Core Directories

Actions (src/actions/)

TanStack Start server actions - backend functions that run on the server.
actions/
├── bible.ts             # Bible API interactions
├── collections.ts       # Collection CRUD operations
├── stories.ts           # Story generation and management
└── auth.ts              # Authentication actions
Purpose: Server-side functions for:
  • Fetching data from external APIs
  • Rate limiting
  • Authentication checks
  • Data validation
Example: bible.ts:10 - Fetches chapter content from API.Bible

Components (src/components/)

components/
├── bible/               # Bible-specific components
│   ├── bible-reader.tsx
│   ├── chapter-navigation.tsx
│   ├── verse-card.tsx
│   └── translation-selector.tsx
├── collections/         # Collection management
│   ├── collection-list.tsx
│   ├── collection-card.tsx
│   ├── add-verse-dialog.tsx
│   └── verse-manager.tsx
├── stories/             # Story-related components
│   ├── story-list.tsx
│   ├── story-card.tsx
│   ├── story-generator-form.tsx
│   └── story-viewer.tsx
├── search/              # Search functionality
│   ├── search-bar.tsx
│   ├── search-results.tsx
│   └── search-pagination.tsx
├── forms/               # Form components
│   ├── sign-in-form.tsx
│   └── sign-up-form.tsx
├── ui/                  # Reusable UI components (shadcn/ui)
│   ├── button.tsx
│   ├── dialog.tsx
│   ├── select.tsx
│   ├── input.tsx
│   └── ...
├── skeletons/           # Loading skeleton components
│   ├── bible-skeleton.tsx
│   ├── collection-skeleton.tsx
│   └── story-skeleton.tsx
├── tabs/                # Tab components
└── profile/             # User profile components
Feature Components (bible/, collections/, stories/, search/):
  • Domain-specific components
  • Can import from ui/ but not from other feature directories
  • May have local state and business logic
UI Components (ui/):
  • Generic, reusable components
  • Based on shadcn/ui
  • No business logic
  • Fully typed with TypeScript
  • Can be used across all features
Skeleton Components (skeletons/):
  • Loading state placeholders
  • Match the layout of actual content
  • Improve perceived performance

Routes (src/routes/)

TanStack Router uses file-based routing. Each file becomes a route.
routes/
├── __root.tsx           # Root layout
├── index.tsx            # Home page (/)
├── bible/
│   └── $bibleId.$chapterId.tsx  # Bible reader (/bible/:bibleId/:chapterId)
├── search.tsx           # Search page (/search)
├── _authed/             # Protected routes (require auth)
│   ├── collections/
│   │   ├── index.tsx    # Collections list
│   │   └── $id.tsx      # Collection detail
│   └── stories/
│       ├── index.tsx    # Stories list
│       ├── new.tsx      # Create story
│       └── $id.tsx      # Story detail
└── api/
    └── auth/            # Auth API routes
        └── $.tsx        # Better Auth catch-all
  • Static routes: about.tsx/about
  • Dynamic routes: $id.tsx/:id
  • Nested routes: blog/$slug.tsx/blog/:slug
  • Layout routes: _layout.tsx → No URL segment, provides layout
  • Protected routes: _authed/ prefix requires authentication
  • Catch-all routes: $.tsx → Matches any remaining path

Hooks (src/hooks/)

hooks/
├── use-bible.ts         # Bible data fetching
├── use-user.ts          # Current user data
├── use-collections.ts   # Collection operations
├── use-stories.ts       # Story operations
└── use-debounce.ts      # Utility hooks
Purpose: Custom React hooks for:
  • Data fetching with TanStack Query
  • Convex real-time subscriptions
  • Shared stateful logic
  • Side effects
Example:
// hooks/use-bible.ts
export function useBibleChapter(bibleId: string, chapterId: string) {
  return useQuery({
    queryKey: ['bible', bibleId, chapterId],
    queryFn: () => fetchChapter(bibleId, chapterId),
  });
}

Library (src/lib/)

lib/
├── utils.ts             # Utility functions (cn, etc.)
├── axios.ts             # API.Bible HTTP client
├── auth.ts              # Better Auth server configuration
├── auth-client.ts       # Better Auth client
├── convex.ts            # Convex utility functions
├── gemini.ts            # Google Gemini AI client
├── redis.ts             # Redis/Upstash rate limiting
├── constants.ts         # App constants
└── uploadthing.ts       # UploadThing configuration
Common utility functions:
  • cn() - Tailwind class name merger using clsx and tailwind-merge
  • Date formatting helpers
  • String manipulation
Pre-configured Axios instance for API.Bible:
  • Base URL set to https://api.scripture.api.bible/v1
  • API key authentication header
  • Request/response interceptors
Better Auth server configuration:
  • Drizzle adapter for PostgreSQL
  • Email/password authentication
  • GitHub OAuth provider
  • Session management
Google Gemini AI client:
  • Model: gemini-1.5-flash
  • API key configuration
  • Error handling
Upstash Redis rate limiting:
  • Fixed window: 5 requests per 24 hours
  • Used for story generation
  • Analytics enabled

Queries (src/queries/)

queries/
├── bible-queries.ts     # TanStack Query configurations for Bible API
├── collection-queries.ts
└── story-queries.ts
Purpose: Centralized query configurations for TanStack Query:
  • Query keys
  • Query functions
  • Caching strategies
  • Refetch policies

Schemas (src/schemas/)

schemas/
├── auth-schema.ts       # Auth form validation
├── collection-schema.ts # Collection validation
└── story-schema.ts      # Story generation validation
Purpose: Zod schemas for:
  • Form validation
  • API request/response validation
  • Type inference
Example:
import { z } from 'zod';

export const createCollectionSchema = z.object({
  name: z.string().min(1, 'Name is required').max(100),
});

export type CreateCollectionInput = z.infer<typeof createCollectionSchema>;

Server (src/server/)

server/
└── api/                 # API route handlers
    └── bible.ts
Purpose: Server-side API handlers and middleware.

Types (src/types/)

types/
├── bible.ts             # Bible API types
├── collection.ts        # Collection types
├── story.ts             # Story types
└── user.ts              # User types
Purpose: TypeScript type definitions:
  • API response types
  • Domain models
  • Utility types
  • Type guards

Styles (src/styles/)

styles/
└── globals.css          # Global styles and Tailwind imports

Database (src/db/)

db/
├── index.ts             # Database connection
└── schema.ts            # Drizzle schema definitions
Purpose: Database configuration for Better Auth’s PostgreSQL storage.

Convex Directory

convex/
├── schema.ts            # Convex database schema
├── collections.ts       # Collection mutations/queries
├── collectionVerses.ts  # Verse operations
├── notes.ts             # Note operations
├── stories.ts           # Story operations
└── _generated/          # Auto-generated TypeScript types
Convex automatically generates TypeScript types from your schema.
Key Files:
schema.ts
file
Defines database tables and indexes:
  • collections - User verse collections
  • collectionVerses - Verses within collections
  • notes - Chapter notes
  • stories - AI-generated stories
See Database Schema for details.
collections.ts
file
Convex functions for collection operations:
  • create - Create new collection
  • update - Update collection name
  • delete - Delete collection
  • list - Get user’s collections
  • get - Get single collection

File Naming Conventions

Components

  • PascalCase for component files: BibleReader.tsx
  • Or kebab-case: bible-reader.tsx
  • Export component with same name as file

Utilities

  • kebab-case: use-bible.ts
  • camelCase for hook files: useBible.ts
  • Descriptive names

Routes

  • kebab-case: search.tsx
  • $ prefix for params: $id.tsx
  • _ prefix for layout routes: _layout.tsx

Types

  • kebab-case: bible-types.ts
  • Or domain-based: bible.ts in types/
  • Export types, not default exports

Where to Add New Features

1

Identify Feature Category

Determine where your feature belongs:
  • Bible readingsrc/components/bible/
  • Collectionssrc/components/collections/
  • Storiessrc/components/stories/
  • Searchsrc/components/search/
  • New category → Create new directory in src/components/
2

Create Components

Add your React components:
src/components/your-feature/
├── your-feature.tsx      # Main component
├── feature-card.tsx      # Sub-components
└── feature-dialog.tsx
3

Add Types

Define TypeScript types:
// src/types/your-feature.ts
export type YourFeature = {
  id: string;
  name: string;
  // ...
};
4

Create Schemas

Add Zod validation schemas:
// src/schemas/your-feature-schema.ts
import { z } from 'zod';

export const yourFeatureSchema = z.object({
  name: z.string().min(1),
});
5

Add Server Actions

If your feature needs backend logic:
// src/actions/your-feature.ts
'use server';

export async function yourFeatureAction(data: FormData) {
  // Server-side logic
}
6

Create Routes

Add pages for your feature:
src/routes/your-feature/
├── index.tsx            # List view
└── $id.tsx              # Detail view
7

Add Convex Functions (if needed)

For real-time data:
// convex/yourFeature.ts
import { mutation, query } from './_generated/server';

export const create = mutation({
  // ...
});
8

Create Custom Hooks

For data fetching and shared logic:
// src/hooks/use-your-feature.ts
export function useYourFeature() {
  // Hook logic
}

Import Aliases

The project uses path aliases configured in tsconfig.json:
// Instead of:
import { Button } from '../../../components/ui/button';

// Use:
import { Button } from '@/components/ui/button';
Available Aliases:
  • @/componentssrc/components
  • @/libsrc/lib
  • @/hookssrc/hooks
  • @/typessrc/types
  • @/actionssrc/actions
  • @/schemassrc/schemas

Code Organization Best Practices

  • Single Responsibility Principle
  • Extract complex logic into hooks
  • Break large components into smaller ones
  • Maximum ~200 lines per component
  • Components for UI
  • Hooks for data and state
  • Actions for server operations
  • Utils for pure functions
Create index.ts files for cleaner imports:
// components/collections/index.ts
export { CollectionCard } from './collection-card';
export { CollectionDialog } from './collection-dialog';

// Usage
import { CollectionCard, CollectionDialog } from '@/components/collections';

Additional Resources

Environment Variables

Complete reference for all environment variables

Database Schema

Convex schema documentation

Integrations

External API and service integrations

Contributing Guide

How to contribute to the project