A modern, self-hosted Applicant Tracking System (ATS) with AI-powered resume extraction.
| Category | Details |
|---|---|
| Jobs | Create & manage job postings with client, location, skills, and status |
| Candidates | Rich candidate profiles with 17 fields per candidate |
| AI Extraction | Auto-fill candidate forms from PDF / image resumes (Gemini + OpenRouter) |
| Excel Export | Export candidate lists with or without resume links |
| Pipeline Statuses | Fully customizable candidate pipeline stages with color coding |
| User Management | Granular per-user permissions (create/read/update/delete per resource) |
| Job Access Control | Restrict users to specific jobs only |
| Resume Access | Fine-grained control over who can view uploaded resumes |
| Auth | JWT-based authentication with 7-day sessions |
| Responsive UI | Works on desktop and mobile |
candsync/
βββ backend/ # Node.js Β· Express Β· SQLite (node:sqlite built-in)
βββ frontend/ # React 18 Β· Vite Β· TailwindCSS Β· Heroicons
Backend dependencies: express, bcryptjs, jsonwebtoken, multer, xlsx, uuid, node-fetch, dotenv
Frontend dependencies: react, react-router-dom, axios, react-hot-toast, @heroicons/react
Node.js 22+ required β uses the built-in
node:sqlitemodule (no separate sqlite3 install needed).
- Node.js 22+ (check with
node --version) - Git
git clone https://github.com/siiiidddexe/candsync.git
cd candsync
# Install all dependencies (backend + frontend)
npm run install:allcd backend
copy .env.example .env # Windows
# cp .env.example .env # macOS/LinuxEdit backend/.env and set at minimum:
JWT_SECRET=your-long-random-secret-hereTo enable AI resume extraction, add at least one API key:
GEMINI_API_KEY=AIza... # Get from https://aistudio.google.com
OPENROUTER_API_KEY=sk-or-... # Get from https://openrouter.aiAPI keys can also be set from the Settings page in the UI after first login.
Option A β One-click (Windows):
Double-click start.bat
Option B β Manual (two terminals):
# Terminal 1 β Backend
cd backend
npm run dev # dev mode (nodemon)
# npm start # production mode
# Terminal 2 β Frontend
cd frontend
npm run dev| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:5000 |
Default credentials:
Email: admin@candsync.com
Password: Admin@123
β οΈ Change the default password immediately after first login.
- Navigate to Jobs (home page)
- Click New Job β fill title, client, location, skills, description
- Click N Candidates on any job card to manage that job's pipeline
- Open a job β click Add
- (Optional) Upload a PDF/image resume and click Auto-Fill with AI β fields populate automatically
- Fill any remaining fields and set the pipeline Status
- Click Save
- Export β downloads an Excel file with all candidate fields
- + Resume β same but includes a resume URL column (requires
withResumepermission)
Go to Users β New User and configure:
- Role:
viewer|editor|admin(purely cosmetic β actual access is permission-based) - Permissions: fine-grained CRUD per resource (Jobs, Candidates, Statuses, Exports)
- Job Access: all jobs, or a specific list of jobs
- Resume Access: toggle per user
- Set Gemini or OpenRouter as primary provider
- Both providers are used as automatic fallback for each other
- Supported resume formats: PDF, JPEG, PNG, GIF, WEBP (up to 10 MB)
- JWT tokens expire after 7 days
- Passwords are hashed with bcrypt (10 rounds)
- Resume files are served only to users with
resumeAccesspermission - Set a strong
JWT_SECRETin production (32+ random characters) - Set
FRONTEND_URLto your actual domain in production to restrict CORS
candsync/
βββ backend/
β βββ middleware/
β β βββ auth.js # JWT verification, permission helpers
β βββ routes/
β β βββ auth.js # Login, /me, change-password
β β βββ candidates.js # CRUD, AI extract, resume serve, export
β β βββ jobs.js # CRUD + candidate count
β β βββ settings.js # AI keys & config
β β βββ statuses.js # Pipeline stages
β β βββ users.js # User management
β βββ uploads/ # Resume files (git-ignored)
β βββ db.js # SQLite schema, seed data
β βββ server.js # Express app entry point
β βββ .env.example # Environment variable template
β βββ package.json
βββ frontend/
β βββ src/
β β βββ api/client.js # Axios instance with auth interceptor
β β βββ context/
β β β βββ AuthContext.jsx
β β βββ components/
β β β βββ Layout.jsx # Sidebar navigation shell
β β βββ pages/
β β β βββ Login.jsx
β β β βββ Jobs.jsx
β β β βββ Candidates.jsx
β β β βββ Statuses.jsx
β β β βββ Users.jsx
β β β βββ Settings.jsx
β β βββ App.jsx
β β βββ index.css # Tailwind + custom components
β βββ package.json
βββ start.bat # Windows one-click launcher
βββ install.bat # Windows one-click installer
βββ package.json # Root convenience scripts
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
MIT Β© 2024 CandSync