An open API service indexing awesome lists of open source software.

https://github.com/divya19gupta/zapply

Upload a CV and a job description, get back a tailored, human-sounding cover letter in about 15 seconds. No generic "I am writing to express my interest" filler.
https://github.com/divya19gupta/zapply

flask mui openai prompt-engineering python react typescript vite

Last synced: 2 days ago
JSON representation

Upload a CV and a job description, get back a tailored, human-sounding cover letter in about 15 seconds. No generic "I am writing to express my interest" filler.

Awesome Lists containing this project

README

          

# ✍️ Zapply

> Upload a CV. Paste a job description. Get a tailored, human-sounding cover letter in about **15 seconds**.

No generic *"I am writing to express my interest..."*. No awkward AI fluff. Just a cover letter that actually sounds like you.

_🌐 **Live app:** https://zapply-cyan.vercel.app_

---

## ✨ Features

- πŸ“„ **Upload your resume** (PDF) and paste the job description, that's literally the entire workflow.
- πŸ€– **AI-generated cover letter** powered by OpenAI `gpt-4.1`
- sounds like a real person, not a template
- skips clichΓ© openings and corporate buzzwords
- mirrors the language and tone of the job posting
- honestly acknowledges career changes instead of pretending they never happened
- πŸ“ **Ready-to-send formatting**
- contact details
- date
- subject line
- professionally structured body
- signature
- πŸ“‹ **Copy with one click** or πŸ“₯ **download as a polished one-page PDF**.

---

## πŸ› οΈ Tech Stack

| Layer | Technology |
|--------|------------|
| **Frontend** | React + Vite + TypeScript, Material UI |
| **Backend** | Flask (Python) |
| **AI** | OpenAI API (`gpt-4.1`) |
| **PDF Parsing** | `pymupdf4llm` |
| **PDF Generation** | `html2pdf.js` |
| **Hosting** | Vercel (frontend) + Render (backend) |

---

## πŸ“‚ Project Structure

```text
Zapply/
β”œβ”€β”€ backend/
β”‚ β”œβ”€β”€ app.py # Flask entrypoint + CORS
β”‚ β”œβ”€β”€ processing.py # Handles uploads and orchestrates the pipeline
β”‚ β”œβ”€β”€ openai_service.py # Prompt engineering + OpenAI calls
β”‚ └── requirements.txt
└── frontend/
└── src/
β”œβ”€β”€ pages/
β”‚ β”œβ”€β”€ UploadPage.tsx
β”‚ └── CoverLetterPage.tsx
└── components/
└── Navbar.tsx
```

---

## πŸš€ Local Setup

### Backend

```bash
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
```

Create a `.env` file:

```env
OPENAI_API_KEY=your_key_here
```

Run:

```bash
python app.py
```

Backend β†’ `http://localhost:5000`

---

### Frontend

```bash
cd frontend
npm install
```

Create a `.env` file:

```env
VITE_API_URL=http://localhost:5000
```

Run:

```bash
npm run dev
```

Frontend β†’ `http://localhost:5173`

---

## πŸ” Environment Variables

| Variable | Location | Purpose |
|-----------|----------|---------|
| `OPENAI_API_KEY` | `backend/.env` | Generates the cover letter |
| `FRONTEND_URL` | Render | Allowed frontend origin for CORS |
| `VITE_API_URL` | Frontend | Backend API URL |

---

## ☁️ Deployment

### Backend (Render)

- Root directory: `backend`
- Build command:
```bash
pip install -r requirements.txt
```
- Start command:
```bash
gunicorn app:app --bind 0.0.0.0:$PORT
```
- Environment variables:
- `OPENAI_API_KEY`
- `FRONTEND_URL`

### Frontend (Vercel)

- Root directory: `frontend`
- Framework preset: **Vite**
- Environment variable:
- `VITE_API_URL` β†’ deployed Render backend URL

---

## ⚠️ Known Limitations

- 🧠 Stateless by design: nothing is stored after a request finishes.
- πŸ”’ CORS is intentionally restricted to approved frontend origins.
- πŸ’» `pymupdf4llm` brings in `onnxruntime`, which may log harmless GPU detection warnings on Render's CPU-only machines.
- 😴 Render's free tier goes to sleep after inactivity, so the first request may take ~30 seconds to wake up.
- πŸ‘€ No authentication: this is a personal project, not a multi-user SaaS.

---

## πŸ’‘ Why I built this

After applying to way too many jobs, I realized the hardest part wasn't updating my CV; it was rewriting the same cover letter over and over again.

Most AI tools either sound overly formal, stuff every sentence with buzzwords, or generate the same generic opening every recruiter has already seen.

So I built **Zapply** to generate cover letters that feel more human: tailored to the job description, grounded in the candidate's actual experience, and ready to send with minimal editing.