A lightweight, self-hostable ATS-optimised CV builder with a live preview editor, keyword analysis engine, and PDF export — all running on your own infrastructure. No SaaS fees. No data leaving your server.
┌─────────────────────────────────────────┐
│ React SPA (Editor · Preview · ATS) │
└──────────────────┬──────────────────────┘
│ HTTPS
┌──────────────────▼──────────────────────┐
│ Nginx (reverse proxy) │
└──────────┬───────────────┬──────────────┘
│ REST │ static
┌──────────▼─────┐ ┌──────▼──────────────┐
│ Express + ORM │ │ Frontend (built) │
│ ATS Engine │ └─────────────────────┘
│ Puppeteer PDF │
└──────────┬─────┘
┌──────────▼─────┐
│ PostgreSQL 15 │
└────────────────┘
MS CV Pro is a self-hostable, open-source CV builder designed for job seekers who want full control over their data and don't want to pay a monthly SaaS subscription to build a PDF document. Most CV builders either lock your data behind a paywall, require a cloud account, or produce ATS-unfriendly PDFs. Here, nothing leaves your server.
| Feature | Description |
|---|---|
| CV Editor | Section-based editor: Personal info, Work, Education, Skills, Projects, Certifications |
| Live Preview | Real-time A4 preview as you type |
| ATS Scoring | Local keyword analysis engine — no API keys needed |
| PDF Export | Clean, ATS-safe PDF via Puppeteer headless Chrome |
| Multi-CV | Unlimited CVs per user, with duplicate support |
| Auth | JWT-based auth with bcrypt password hashing |
| Self-hosted | Single docker compose up deployment |
- Docker ≥ 24 and Docker Compose ≥ 2.24
- 1 GB RAM minimum (Puppeteer needs ~300 MB for Chrome)
git clone https://github.com/shafeehhecker/MS_CV-Pro.git
cd MS_CV-Pro
cp .env.example .env
# Edit .env — at minimum set DB_PASSWORD and JWT_SECRETdocker compose up -d --buildFirst boot takes 3-5 minutes (npm install + Chrome download + DB migration).
docker compose ps
curl http://localhost/api/healthdocker compose exec api npm run db:seed
# Demo login: demo@mscvpro.local / demo1234Open http://localhost — you're ready.
- Node.js 20+
- PostgreSQL 15 running locally
cd backend
cp .env.example .env
# Edit DATABASE_URL in .env
npm install
npx prisma migrate dev
npm run db:seed # optional demo data
npm run dev
# API running at http://localhost:3001cd frontend
npm install
npm run dev
# App running at http://localhost:5173- Point your domain to the server IP
- Get certificates:
apt install certbot certbot certonly --standalone -d yourdomain.com
- Copy certs to
nginx/ssl/:cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem nginx/ssl/ cp /etc/letsencrypt/live/yourdomain.com/privkey.pem nginx/ssl/
- Uncomment the HTTPS server block in
nginx/nginx.conf - Update
.env:CORS_ORIGIN=https://yourdomain.com docker compose up -d --build
git pull
docker compose up -d --buildPrisma migrations run automatically on container start.
MS_CV-Pro/
├── backend/
│ ├── src/
│ │ ├── index.js # Express app entry
│ │ ├── middleware/
│ │ │ └── auth.js # JWT middleware
│ │ ├── routes/
│ │ │ ├── auth.js # Register / login / me
│ │ │ ├── cv.js # Full CV CRUD + sections
│ │ │ ├── ats.js # ATS scoring endpoint
│ │ │ ├── export.js # PDF + HTML preview
│ │ │ └── upload.js # Profile photo upload
│ │ └── services/
│ │ ├── atsEngine.js # Local TF-IDF keyword engine
│ │ └── pdfExport.js # Puppeteer HTML→PDF
│ └── prisma/
│ ├── schema.prisma
│ ├── seed.js
│ └── migrations/
├── frontend/
│ └── src/
│ ├── pages/ # Login, Register, Dashboard, Editor
│ ├── components/
│ │ ├── editor/ # All form sections
│ │ ├── preview/ # Live CV renderer
│ │ └── ats/ # ATS score panel
│ └── store/ # Zustand (auth + CV state)
├── nginx/
│ └── nginx.conf
└── docker-compose.yml
The scoring engine (backend/src/services/atsEngine.js) runs entirely locally:
- Keyword extraction — tokenises the job description using TF-IDF-inspired frequency weighting, extracting unigrams and bigrams after stop-word removal
- Keyword matching — checks which JD keywords appear in the CV text
- Section scoring — checks for presence of key sections (summary, quantified achievements, dates, contact info)
- Format scoring — flags ATS red flags (missing email/phone, too-sparse content, undated experience)
- Scoring — weighted composite: keywords 45%, sections 35%, format 20%
No external API calls are made during scoring.
| Variable | Default | Description |
|---|---|---|
DB_PASSWORD |
mscvpro_secret |
PostgreSQL password |
JWT_SECRET |
change-me |
JWT signing secret — must change in production |
NODE_ENV |
production |
Node environment |
CORS_ORIGIN |
http://localhost |
Allowed CORS origin |
HTTP_PORT |
80 |
Host HTTP port |
HTTPS_PORT |
443 |
Host HTTPS port |
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, Zustand, React Router |
| Backend | Node.js 20, Express 4, Prisma ORM |
| Database | PostgreSQL 15 |
| Puppeteer (headless Chrome) | |
| ATS Engine | Custom TF-IDF (no external APIs) |
| Proxy | Nginx |
| Container | Docker Compose |
MIT