--- title: "Development Setup" description: "Set up a local development environment for Reactive Resume" --- **Prerequisites**: - [Node.js](https://nodejs.org/) v20 or higher - [pnpm](https://pnpm.io/) v10.28.0 or higher (package manager) - [Docker](https://docs.docker.com/get-docker/) and Docker Compose - [Git](https://git-scm.com/) This guide walks you through setting up Reactive Resume for local development. Whether you're contributing to the project or customizing it for your needs, these steps will get you up and running. --- ## Setting Up Your Development Environment ```bash git clone https://github.com/amruthpillai/reactive-resume.git cd Reactive-Resume ``` This project uses [pnpm](https://pnpm.io/) as its package manager for its speed and efficiency. ```bash # Install pnpm if you haven't already npm install -g pnpm # Install project dependencies pnpm install ``` Start the required services using the development-specific Docker Compose file: ```bash docker compose -f compose.dev.yml up -d ``` This starts the following infrastructure services: - **PostgreSQL** — Database (port 5432) - **SeaweedFS** — S3-compatible storage (port 8333) - **Mailpit** — Email testing server (SMTP on port 1025, UI on port 8025) **From v5.1.0 onwards** — PDF generation now runs entirely in the browser via `@react-pdf/renderer`, so no Browserless or Chromium container is required for development. Use `compose.dev.yml` instead of `compose.yml` for local development. The development file only includes infrastructure services with ports exposed to your host machine, while the main `compose.yml` includes the full application stack intended for production deployments. Wait for all services to be healthy before proceeding. Check with `docker compose -f compose.dev.yml ps`. Create a `.env` file in the project root: ```bash # Server APP_URL=http://localhost:3000 # Database DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres # Authentication AUTH_SECRET=development-secret-change-in-production # Storage (SeaweedFS) S3_ACCESS_KEY_ID=seaweedfs S3_SECRET_ACCESS_KEY=seaweedfs S3_ENDPOINT=http://localhost:8333 S3_BUCKET=reactive-resume S3_FORCE_PATH_STYLE=true # Email (Mailpit for local development) SMTP_HOST=localhost SMTP_PORT=1025 ``` **Email Testing**: The development stack includes [Mailpit](https://mailpit.axllent.org/), an email testing tool. All emails sent by the application will be captured and viewable at [http://localhost:8025](http://localhost:8025). No emails will actually be sent to real addresses during development. Apply the database schema: ```bash pnpm run db:migrate ``` ```bash pnpm run dev ``` Your local Reactive Resume instance will be available at [http://localhost:3000](http://localhost:3000). --- ## Available Scripts Here are the most commonly used scripts during development: ### Development | Command | Description | | -------------------- | -------------------------------------------- | | `pnpm run dev` | Start the development server with hot reload | | `pnpm run build` | Build the application for production | | `pnpm run start` | Start the production server | | `pnpm run lint` | Run Oxlint linter and formatter | | `pnpm run format` | Run Oxfmt formatter | | `pnpm run typecheck` | Run TypeScript type checking | ### Database | Command | Description | | ---------------------- | -------------------------------------------- | | `pnpm run db:generate` | Generate migration files from schema changes | | `pnpm run db:migrate` | Apply pending migrations | | `pnpm run db:studio` | Open Drizzle Studio (database GUI) | ### Internationalization | Command | Description | | ------------------------- | -------------------------------------- | | `pnpm run lingui:extract` | Extract translatable strings from code | ### Documentation | Command | Description | | ------------------- | ------------------------------------------ | | `pnpm run docs:dev` | Start the Mintlify docs development server | --- ## Understanding the Project Structure Understanding the project structure will help you navigate the codebase: ``` reactive-resume/ ├── src/ │ ├── components/ # Reusable React components │ │ ├── ui/ # Base UI components (Button, Card, etc.) │ │ ├── resume/ # Resume-specific components │ │ └── ... │ ├── dialogs/ # Modal dialogs │ ├── hooks/ # Custom React hooks │ ├── integrations/ # Third-party integrations │ │ ├── auth/ # Better Auth integration │ │ ├── drizzle/ # Database schema & utilities │ │ └── orpc/ # API routes & services │ ├── routes/ # File-based routing (TanStack Router) │ │ ├── builder/ # Resume builder pages │ │ ├── dashboard/ # User dashboard │ │ ├── auth/ # Authentication pages │ │ └── ... │ ├── schema/ # Zod schemas for validation │ ├── utils/ # Utility functions │ └── styles/ # Global CSS styles ├── public/ # Static assets ├── locales/ # Translation files (.po format) ├── migrations/ # Database migrations ├── docs/ # Mintlify documentation └── data/ # Local data (fonts, uploads) ``` --- ## Working with the Database ### Viewing the Database Use Drizzle Studio to explore and manage your database: ```bash pnpm run db:studio ``` This opens a web-based GUI at [https://local.drizzle.studio](https://local.drizzle.studio). ### Making Schema Changes 1. Edit the schema in `src/integrations/drizzle/schema.ts` 2. Generate a migration: ```bash pnpm run db:generate ``` 3. Apply the migration: ```bash pnpm run db:migrate ``` Always review generated migrations before applying them, especially when working with existing data. --- ## Working with Translations Reactive Resume uses [Lingui](https://lingui.dev/) for internationalization. ### Adding Translatable Text Use the `t` macro for strings or `` component for JSX: ```tsx import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; // For plain strings const message = t`Hello, World!`; // For JSX content Welcome to Reactive Resume; ``` ### Extracting Translations After adding new translatable text, extract them to the locale files: ```bash pnpm run lingui:extract ``` Translation files are located in the `locales/` directory in `.po` format. --- ## Code Quality ### Linting & Formatting Uses [Oxlint](https://oxlint.dev/) for linting and [Oxfmt](https://oxfmt.dev/) for formatting: ```bash # Check and auto-fix issues pnpm run lint:fix pnpm run format:fix ``` ### Type Checking Run TypeScript type checking: ```bash pnpm run typecheck ``` Configure your IDE to use Oxlint for automatic linting and Oxfmt for automatic formatting on save. For VS Code, install the [Oxlint extension](https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode) and configure the settings in `.vscode/settings.json`. --- ## Troubleshooting Another process is using port 3000. Either stop that process or start the dev server on a different port: ```bash PORT=3001 pnpm run dev ``` Ensure Docker containers are running: ```bash docker compose -f compose.dev.yml ps docker compose -f compose.dev.yml up -d ``` Check that PostgreSQL is healthy and accessible on port 5432. Verify SeaweedFS is running and the bucket exists: ```bash docker compose -f compose.dev.yml logs seaweedfs docker compose -f compose.dev.yml logs seaweedfs_create_bucket ``` If the bucket wasn't created, restart the bucket creation service: ```bash docker compose -f compose.dev.yml restart seaweedfs_create_bucket ``` The route tree may need regeneration. Run the dev server which auto-generates routes: ```bash pnpm run dev ``` Or run type checking to see specific errors: ```bash pnpm run typecheck ``` --- ## Next Steps Deep dive into the project architecture and codebase structure. View the source code and contribute to the project.