--- title: "Project Architecture" description: "Understand the architecture and codebase structure of Reactive Resume" --- This guide provides a comprehensive overview of Reactive Resume's architecture and codebase structure, helping you understand how different parts of the application work together. --- ## Tech Stack Overview Reactive Resume is built with a modern, type-safe stack: - **React 19** with TanStack Start - **TypeScript** for type safety - **Tailwind CSS** for styling - **Radix UI** for accessible components - **ORPC** for type-safe RPC - **Drizzle ORM** with PostgreSQL - **Better Auth** for authentication - **Sharp** for image processing --- ## Application Architecture ```mermaid flowchart TD %% Client Side subgraph Client ["Client"] Router["TanStack Router"] Query["TanStack Query"] ORPCClient["oRPC Client"] end %% Server Side subgraph Server ["Server"] ORPCRouter["oRPC Router"] Auth["Better Auth"] Services["Services Layer"] Drizzle["Drizzle ORM"] end Database["PostgreSQL"] Storage["File System OR S3-Compatible Storage"] Printer["Printer (Browserless/Chromium)"] Router --> ORPCClient Query --> ORPCClient ORPCClient -- calls --> ORPCRouter ORPCRouter --> Services Auth --> Services Services --> Drizzle Drizzle --> Database Services --> Storage Services --> Printer ``` **Diagram:** This flow shows data and control flow between the main architectural layers of Reactive Resume. --- ## Directory Structure ### Root Level | Directory | Purpose | | ------------- | ----------------------------------- | | `src/` | Main application source code | | `public/` | Static assets served directly | | `locales/` | Translation files (.po format) | | `migrations/` | Database migration files | | `docs/` | Mintlify documentation | | `data/` | Local data storage (fonts, uploads) | | `scripts/` | Utility scripts | ### Source Code (`src/`) Reusable React components organized by category: - **`ui/`** — Base UI components (Button, Card, Dialog, etc.) - **`resume/`** — Resume-specific components (sections, templates) - **`input/`** — Form input components (ColorPicker, RichInput) - **`layout/`** — Layout components (Sidebar, LoadingScreen) - **`animation/`** — Animation components (Spotlight, TextMask) - **`theme/`** — Theme management components - **`typography/`** — Font management components File-based routing using TanStack Router: - **`__root.tsx`** — Root layout with providers - **`_home/`** — Public home page routes - **`auth/`** — Authentication routes (login, register, etc.) - **`dashboard/`** — User dashboard routes - **`builder/`** — Resume builder routes (the main editor) - **`printer/`** — PDF printing route - **`api/`** — API routes Third-party service integrations: - **`auth/`** — Better Auth client configuration - **`drizzle/`** — Database schema and utilities - **`orpc/`** — API router, client, and services - **`ai/`** — AI service integrations - **`import/`** — Resume import utilities Modal dialog components: - **`auth/`** — Authentication dialogs - **`resume/`** — Resume management dialogs - **`api-key/`** — API key management dialogs - **`manager.tsx`** — Dialog manager component - **`store.ts`** — Dialog state management (Zustand) Zod schemas for validation: - **`resume/`** — Resume data schemas - **`icons.ts`** — Icon definitions - **`templates.ts`** — Template definitions Custom React hooks: - `use-confirm.tsx` — Confirmation dialog hook - `use-prompt.tsx` — Prompt dialog hook - `use-mobile.tsx` — Mobile detection hook - `use-safe-context.tsx` — Safe context consumption Utility functions: - `env.ts` — Environment variable validation - `locale.ts` — Locale utilities - `theme.ts` — Theme utilities - `string.ts` — String manipulation - `file.ts` — File handling utilities --- ## Key Concepts ### File-Based Routing Routes are automatically generated from the file structure in `src/routes/`. TanStack Router conventions: | Pattern | Description | Example | | ------------ | --------------------- | -------------------- | | `index.tsx` | Index route | `/dashboard` | | `$param.tsx` | Dynamic parameter | `/builder/$resumeId` | | `_layout/` | Layout group (prefix) | `_home/` | | `__root.tsx` | Root layout | Wraps all routes | Never edit `src/routeTree.gen.ts` manually — it's auto-generated when you run the dev server. ### API Layer (ORPC) ORPC provides end-to-end type safety for API calls: ``` src/integrations/orpc/ ├── client.ts # Client-side ORPC setup ├── router/ # API route definitions │ ├── auth.ts # Authentication endpoints │ ├── resume.ts # Resume CRUD operations │ └── storage.ts # File storage operations ├── services/ # Business logic layer └── helpers/ # Utility functions ``` **Using the API client:** ```tsx import { useQuery } from "@tanstack/react-query"; import { orpc } from "@/integrations/orpc/client"; // Type-safe API calls with TanStack Query const { data } = useQuery(orpc.resume.findMany.queryOptions()); ``` ### State Management Reactive Resume uses a hybrid approach: | Type | Tool | Use Case | | ------------ | --------------- | ------------------------------ | | Server State | TanStack Query | API data, caching, sync | | Client State | Zustand | UI state, dialogs, preferences | | Form State | React Hook Form | Form inputs and validation | ### Database Schema The database schema is defined using Drizzle ORM in `src/integrations/drizzle/schema.ts`: ```tsx import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core"; export const resume = pgTable("resume", { id: uuid("id").primaryKey().defaultRandom(), title: text("title").notNull(), slug: text("slug").notNull(), // ... more fields }); ``` --- ## Common Development Patterns ### Adding a New Component 1. Create the component in the appropriate `src/components/` subdirectory 2. Export it from the directory's index file (if applicable) 3. Use TypeScript props interfaces for type safety 4. Follow existing patterns for consistency ```tsx // src/components/ui/my-component.tsx import { cn } from "@/utils/style"; interface MyComponentProps { title: string; className?: string; } export const MyComponent = ({ title, className }: MyComponentProps) => { return
{title}
; }; ``` ### Adding a New Route 1. Create a new file in `src/routes/` following TanStack Router conventions 2. The route tree auto-generates when you save 3. Use `createFileRoute` for type-safe routes ```tsx // src/routes/my-page.tsx import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute("/my-page")({ component: MyPage, }); function MyPage() { return
My Page Content
; } ``` ### Adding an API Endpoint 1. Add the route handler in `src/integrations/orpc/router/` 2. Create service functions in `src/integrations/orpc/services/` if needed 3. The endpoint is automatically typed on the client ```tsx // In router file import { z } from "zod"; import { publicProcedure, router } from "../server"; export const myRouter = router({ hello: publicProcedure.input(z.object({ name: z.string() })).handler(async ({ input }) => { return { message: `Hello, ${input.name}!` }; }), }); ``` ### Adding Translations 1. Wrap text with `t` macro or `` component 2. Run `pnpm run lingui:extract` to update locale files 3. Edit the `.po` files in `locales/` to add translations ```tsx import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; // In component const title = t`Welcome`; Click here to continue; ``` --- ## Configuration Files | File | Purpose | | ------------------- | --------------------------------- | | `vite.config.ts` | Vite bundler configuration | | `tsconfig.json` | TypeScript configuration | | `.oxfmtrc.json` | Formatter settings | | `.oxlintrc.json` | Linter settings | | `drizzle.config.ts` | Drizzle ORM configuration | | `lingui.config.ts` | Lingui i18n configuration | | `components.json` | shadcn/ui component configuration | --- ## Contributing Guidelines Fork the repository on GitHub and clone your fork locally. Create a feature branch from `main`: ```bash git checkout -b feature/my-feature ``` Implement your changes following the patterns described above. Ensure the app works correctly with your changes: ```bash pnpm run dev pnpm run lint pnpm run typecheck ``` Write clear commit messages and push to your fork. Open a PR against the main repository with a clear description of your changes. Make sure to read any `CONTRIBUTING.md` file in the repository for additional guidelines. --- ## Need Help? Ask questions and discuss ideas with the community. Report bugs or request features.