Skip to main content
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:

Frontend

  • React 19 with TanStack Start
  • TypeScript for type safety
  • Tailwind CSS for styling
  • Radix UI for accessible components

Backend

  • ORPC for type-safe RPC
  • Drizzle ORM with PostgreSQL
  • Better Auth for authentication
  • Sharp for image processing

Application Architecture

Diagram: This flow shows data and control flow between the main architectural layers of Reactive Resume.

Directory Structure

Root Level

DirectoryPurpose
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:
PatternDescriptionExample
index.tsxIndex route/dashboard
$param.tsxDynamic parameter/builder/$resumeId
_layout/Layout group (prefix)_home/
__root.tsxRoot layoutWraps 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:
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:
TypeToolUse Case
Server StateTanStack QueryAPI data, caching, sync
Client StateZustandUI state, dialogs, preferences
Form StateReact Hook FormForm inputs and validation

Database Schema

The database schema is defined using Drizzle ORM in src/integrations/drizzle/schema.ts:
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
// src/components/ui/my-component.tsx
import { cn } from "@/utils/style";

interface MyComponentProps {
  title: string;
  className?: string;
}

export const MyComponent = ({ title, className }: MyComponentProps) => {
  return <div className={cn("p-4", className)}>{title}</div>;
};

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
// src/routes/my-page.tsx
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/my-page")({
  component: MyPage,
});

function MyPage() {
  return <div>My Page Content</div>;
}

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
// 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 <Trans> component
  2. Run bun run lingui:extract to update locale files
  3. Edit the .po files in locales/ to add translations
import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";

// In component
const title = t`Welcome`;
<Trans>Click here to continue</Trans>

Configuration Files

FilePurpose
vite.config.tsVite bundler configuration
tsconfig.jsonTypeScript configuration
biome.jsonLinter and formatter settings
drizzle.config.tsDrizzle ORM configuration
lingui.config.tsLingui i18n configuration
components.jsonshadcn/ui component configuration

Contributing Guidelines

1

Fork & Clone

Fork the repository on GitHub and clone your fork locally.
2

Create a Branch

Create a feature branch from main:
git checkout -b feature/my-feature
3

Make Changes

Implement your changes following the patterns described above.
4

Test Locally

Ensure the app works correctly with your changes:
bun run dev
bun run check
bun run typecheck
5

Commit & Push

Write clear commit messages and push to your fork.
6

Open a Pull Request

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?