Stop sending generic resumes. Get tailored CVs for every opportunity.
Try It Free | Quick Start | Features | 简体中文
Use Winning CV instantly at: https://winning-cv.jackhui.com.au
- Zero setup — just sign in and start
- Free to use (fair use limits apply)
- All features available via the web
Tip: Try the hosted version first to see the full capabilities before setting up locally!
Winning CV is an open-source application that transforms how you apply for jobs. Instead of manually tailoring resumes for each position, our intelligent system:
- Scans job platforms — LinkedIn, Seek, Indeed, Glassdoor, and Google Jobs
- Analyzes every listing against your base CV using semantic NLP
- Scores compatibility (0-10) so you know where to focus
- Generates tailored resumes optimized for each specific role
- Notifies you instantly via Email, Telegram, or WeChat when great matches appear
The result? Less time on applications, higher interview rates.
- Real-time crawling of LinkedIn, Seek, Indeed, Glassdoor, Google Jobs
- Advanced filtering by location, keywords, and job parameters
- Automatic duplicate detection and priority sorting
- LinkedIn cookie health monitoring for reliable scraping
- Semantic analysis of job descriptions vs. your base CV using spaCy NLP
- Compatibility scoring system (0-10 scale)
- CV-JD fit analysis with detailed breakdown
- Skills gap identification and recommendations
- Context-aware resume customization via Azure AI
- Position-specific keyword optimization
- Format preservation (PDF/DOCX)
- Achievement highlighting based on job requirements
- Automatic versioning for every generated CV
- MinIO-powered secure storage with presigned URLs
- Category detection and custom tagging
- Fork, archive, restore, and delete versions
- Usage and response tracking with analytics
- Select from library before job search
- Email — SMTP-based notifications with customizable templates
- Telegram — Instant alerts via bot with your Chat ID
- WeChat — Direct messaging via custom WeChat API integration
- Test notifications from profile settings
- Detailed job information in every notification
- All Matches in One Place — View every matched job with CV generation status
- Smart Sorting — Sort by newest first or highest match score
- Quick Stats — Total matches, CVs generated, pending CVs, average match score
- One-Click CV Generation — Generate tailored CV directly from any job match
- CV Status Tracking — See which jobs have CVs generated and when
- Interactive Stats — Total matches, CVs generated, average scores
- Recent Matches Preview — Quick view of latest job matches
- CV Analytics — Track which CV versions get the best response rates
- Performance Metrics — Monitor your job search effectiveness
- Microsoft OAuth integration
- Token-based API authentication
- Secure session management
- Per-user notification preferences
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, HeroUI |
| Backend | FastAPI, Python 3.10+ |
| Admin UI | Streamlit with OAuth |
| Storage | MinIO (S3-compatible), Airtable |
| NLP | spaCy with en_core_web_sm |
| Containerization | Docker, Docker Compose |
The fastest way to get started with all services running:
# Clone the repository
git clone https://github.com/jack-jackhui/winning-cv.git
cd winning-cv
# Create configuration file
cp env.example .env
# Edit .env with your API keys and settings (see Configuration section)
# Start all services
docker compose up -dAccess points:
- React Frontend: http://localhost:13000
- FastAPI Backend: http://localhost:8000
- API Documentation: http://localhost:8000/api/docs
- MinIO Console: http://localhost:9001
For contributors and developers who want full control:
# Clone and setup
git clone https://github.com/jack-jackhui/winning-cv.git
cd winning-cv
# Create configuration
cp env.example .env
# Install Python dependencies (requires Python 3.10+)
pip install uv # or: brew install uv
uv pip install -r requirements.txt
# Install spaCy language model
python -m spacy download en_core_web_sm
# Configure browser path in .env
# macOS: CHROME_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
# Windows: CHROME_PATH="C:\Program Files\Google\Chrome\Application\chrome.exe"
# Set: HEADLESS=false and RUNNING_IN_DOCKER=falseRun the services:
# Terminal 1: FastAPI Backend
python run_api.py
# API at http://localhost:8000, Docs at http://localhost:8000/api/docs
# Terminal 2: React Frontend (for development)
cd frontend && npm install && npm run dev
# Frontend at http://localhost:3000
# Terminal 3: Streamlit Admin UI
python webui_new.py
# Admin UI at http://localhost:8501
# Or run CLI job search
python main.py --user-email your@email.com- Sign In — Use Microsoft OAuth
- Configure Search — Enter job keywords, location, and preferences
- Select CV — Choose from your CV library or upload a new one
- Run Search — System scrapes jobs and scores matches in real-time
- Browse Job Matches — View all matches sorted by date or score, see CV status for each
- Generate Tailored CVs — Click "Generate CV" on any job to create an optimized resume
- Download & Apply — View, download, or share your generated CVs
- Track Performance — Use analytics to see which CV versions get the best results
# Set job search URLs in .env
LINKEDIN_JOB_URL=https://linkedin.com/jobs/search?keywords=...
SEEK_JOB_URL=https://seek.com.au/...
# Run the job processor
python main.py --user-email your@email.comJobs are analyzed, CVs generated, and notifications sent automatically.
All settings are managed via .env file. Copy env.example and configure:
Click to expand full configuration reference
# === Base CV ===
BASE_CV_PATH=user_cv/my_resume.docx
# === Airtable (Data Storage) ===
AIRTABLE_PAT=your-personal-access-token
AIRTABLE_BASE_ID=your-base-id
AIRTABLE_TABLE_ID=main-jobs-table-id
AIRTABLE_TABLE_ID_HISTORY=history-table-id
AIRTABLE_TABLE_ID_USER_CONFIGS=user-configs-table-id
AIRTABLE_TABLE_ID_CV_VERSIONS=cv-versions-table-id
# === MinIO (CV File Storage) ===
MINIO_ENDPOINT=localhost:9000 # or minio:9000 in Docker
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin123
MINIO_BUCKET=winningcv-cvs
# === Job Board URLs (CLI mode) ===
LINKEDIN_JOB_URL=https://linkedin.com/jobs/search?...
SEEK_JOB_URL=https://seek.com.au/...
# === Azure AI ===
AZURE_AI_ENDPOINT=https://your-endpoint.openai.azure.com
AZURE_AI_API_KEY=your-api-key
AZURE_DEPLOYMENT=deployment-name
# === Notifications ===
# Email
EMAIL_USER=your@email.com
EMAIL_PASSWORD=your-password
SMTP_SERVER=smtp.server.com
DEFAULT_FROM_EMAIL=noreply@example.com
DEFAULT_TO_EMAIL=your@email.com
# Telegram
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=your-chat-id
# WeChat (Direct API)
WECHAT_API_URL=https://your-wechat-api.com
WECHAT_API_KEY=your-api-key
# === Search Parameters ===
LOCATION=Melbourne,VIC
COUNTRY=Australia
HOURS_OLD=168 # Jobs from last 7 days
RESULTS_WANTED=10 # Jobs per platform
JOB_MATCH_THRESHOLD=7 # Minimum match score (0-10)
MAX_JOBS_TO_SCRAPE=50
# === Browser (Local Development) ===
CHROME_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
HEADLESS=false
RUNNING_IN_DOCKER=falsewinning-cv/
├── frontend/ # React + Vite + Tailwind dashboard
│ └── src/
│ ├── pages/ # Dashboard, CVLibrary, Analytics, Profile, etc.
│ ├── components/ # Reusable UI components
│ ├── context/ # Auth context
│ └── services/ # API client
├── api/ # FastAPI REST backend
│ ├── routes/ # auth, cv, cv_versions, jobs, profile
│ ├── middleware/ # Authentication middleware
│ └── schemas/ # Pydantic models
├── job_processing/ # Core matching engine
├── job_sources/ # Platform scrapers (LinkedIn, Seek, etc.)
│ └── linkedin_cookie_health.py # Cookie monitoring
├── data_store/ # Airtable + CV version manager
├── cv/ # CV parsing & generation
├── utils/ # MinIO storage, notifications, logging
├── scheduler/ # APScheduler background jobs
├── webui_new.py # Streamlit admin application
├── main.py # CLI interface
└── run_api.py # FastAPI server entry point
| Service | Port | Description |
|---|---|---|
frontend |
13000 | React SPA via Nginx |
api |
8000 | FastAPI REST backend |
job-runner |
- | CLI batch processor |
minio |
9000/9001 | S3-compatible storage |
The FastAPI backend provides a complete REST API:
| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/me |
GET | Get auth status |
/api/v1/auth/user |
GET | Get user info |
/api/v1/auth/login-url |
GET | Get OAuth login URL |
/api/v1/auth/logout |
POST | Logout |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/jobs/config |
GET | Get job search config |
/api/v1/jobs/config |
POST | Save job search config |
/api/v1/jobs/search |
POST | Start job search |
/api/v1/jobs/search/{task_id}/status |
GET | Get search status |
/api/v1/jobs/results |
GET | List matched jobs (supports sort_by=date|score) |
/api/v1/jobs/linkedin/health |
GET | LinkedIn cookie health |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/cv/versions |
GET | List CV versions |
/api/v1/cv/versions |
POST | Create CV version |
/api/v1/cv/versions/{id} |
GET | Get version details |
/api/v1/cv/versions/{id} |
PATCH | Update version |
/api/v1/cv/versions/{id} |
DELETE | Delete version |
/api/v1/cv/versions/{id}/download |
GET | Get download URL |
/api/v1/cv/versions/{id}/fork |
POST | Fork version |
/api/v1/cv/versions/analytics/summary |
GET | Get analytics |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/profile/notifications |
GET | Get notification preferences |
/api/v1/profile/notifications |
PUT | Update preferences |
/api/v1/profile/notifications/test |
POST | Send test notification |
Full interactive docs at: http://localhost:8000/api/docs
# Never commit secrets
echo ".env" >> .gitignore
# Restrict file permissions
chmod 600 .env- Rotate credentials regularly
- Use environment variables in CI/CD
- Keep API keys and tokens secure
- Local LLM support with Ollama
- Browser extension for one-click applications
- Salary negotiation assistant
- Application success analytics dashboard
- Mobile app (iOS/Android)
- More job platforms integration
- Community plugin marketplace
We welcome contributions! Here's how you can help:
- Report bugs via GitHub Issues
- Submit PRs for features and fixes
- Develop platform connectors for new job sites
- Improve documentation and tutorials
- Share your success stories
Please read our Contribution Guidelines before submitting PRs.
Released under the MIT License.
- Job data comes from third-party platforms
- Users must comply with each platform's Terms of Service
- Always review generated CVs before submission
- Not affiliated with LinkedIn, Seek, Indeed, or other job platforms
Transform Your Job Search Today
Try Winning CV Free | View Documentation
Star this repo to support development!
Built with these amazing open-source technologies:
- JobSpy — Multi-platform job scraping
- FastAPI — Modern Python web framework
- React — UI component library
- HeroUI — React component library
- Streamlit — Rapid dashboard development
- MinIO — S3-compatible object storage
- spaCy — Industrial NLP
- Docker — Containerization
Special thanks to all open-source maintainers and contributors who make projects like this possible.