AI Photo Generator is a full-stack web application that allows users to train custom AI models based on their own photos and then generate new, studio-quality portraits using text prompts.
This project leverages the power of Fal.ai for efficient LoRA model training and image generation, Clerk for seamless user authentication, and a robust Next.js and Express backend all managed within a Turborepo monorepo.
- User Authentication: Secure sign-up and sign-in functionality powered by Clerk.
- Custom Model Training: Users can upload a set of their images to train a personalized LoRA model. The training process is handled asynchronously.
- AI Image Generation: Generate high-quality images from text prompts using your trained models.
- Personalized Dashboard: A central hub for users to manage their trained models, generate new images, and view their gallery of creations.
- Direct-to-Cloud Uploads: Utilizes pre-signed URLs for secure and efficient uploading of training images directly to an S3-compatible object store (like Cloudflare R2).
- Webhook Integration: Real-time status updates for model training and image generation via webhooks from Fal.ai.
- Framework: Next.js (App Router)
- Backend API: Express.js on Bun
- AI Provider: Fal.ai
- Monorepo: Turborepo
- Database: PostgreSQL with Prisma ORM
- Authentication: Clerk
- File Storage: S3-compatible object storage (e.g., Cloudflare R2)
- Styling: Tailwind CSS with shadcn/ui
- Language: TypeScript
This repository is a Turborepo monorepo.
apps/web: The main Next.js frontend application. It includes the UI, user dashboard, API routes to communicate with the backend, and Clerk integration.apps/backend: An Express.js backend service responsible for handling core business logic, such as initiating model training and image generation jobs with Fal.ai.packages/db: Contains the Prisma schema, client, and migration files for the PostgreSQL database.packages/common: Shared code, primarily Zod types for validation between the frontend and backend.packages/ui: A stub for shared React components.packages/typescript-config: Shared TypeScript configurations.packages/eslint-config: Shared ESLint configurations.
- Upload Form: The user fills out a form on the frontend with model details and selects 10-20 images.
- Pre-signed URL: The frontend requests a pre-signed URL from the
/api/pre-signed-urlendpoint. - Direct Upload: The frontend zips the selected images and uploads the ZIP file directly to the S3-compatible bucket using the pre-signed URL.
- Initiate Training: The frontend sends the model details and the S3 URL of the ZIP file to the
/api/trainingendpoint. - Fal.ai Job: The backend API initiates a training job on Fal.ai, providing the image data URL and a webhook URL for completion notification.
- Database Record: A new model record is created in the database with a
Pendingstatus. - Webhook Notification: Upon completion, Fal.ai sends a request to the
/api/trainmodelwebhookendpoint. The handler updates the model's status toGeneratedand saves the resulting LoRA model's path (tensorPath).
- Generate Form: From the dashboard, the user selects a trained model and enters a text prompt.
- API Request: The frontend sends the prompt and model ID to the
/api/generateendpoint. - Fal.ai Job: The backend initiates an image generation job on Fal.ai, providing the prompt and the model's unique
tensorPath. The job is configured to use a webhook for real-time updates. - Real-time Updates: The frontend subscribes to real-time events from Fal.ai to display the generated image as soon as it's ready.
- Save Image: The user can choose to save the generated image, which sends the image URL, prompt, and other details to the
/api/saveimageendpoint to be persisted in the database.
Create a .env file in the root of the apps/web directory and add the following variables:
# Database
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE"
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
# Fal.ai API Key
FAL_KEY="your-fal-secret-key"
# S3/R2 Cloud Storage
ENDPOINT="https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
BUCKET_NAME="your-bucket-name"
S3_ACCESS_KEY="your-access-key-id"
S3_SECRET_KEY="your-secret-access-key"
NEXT_PUBLIC_R2_ENDPOINT="your-public-r2-bucket-url"
# Application URLs
WEBHOOK_BASE_URL="http://localhost:3000"
# Custom JWT Secret (for backend-to-backend communication if needed)
AUTH_JWT_KEY="your-strong-secret-key"Follow these steps to get the project running locally.
git clone https://github.com/saady789/AIPhotoGenerator.git
cd AIPhotoGenerator/appThis project uses bun as the package manager.
bun installMake sure you have a PostgreSQL database running and have updated the DATABASE_URL in your .env file. Then, push the schema to your database.
cd packages/db
npx prisma db pushThis command will start both the Next.js frontend and the Express backend concurrently using Turborepo.
bun run dev- The frontend will be available at http://localhost:3000.
- The backend will be running on http://localhost:8000.