A full-stack enterprise-grade HRMS built for modern teams — featuring real-time attendance tracking, automated payroll, leave management, and role-based dashboards with a premium glassmorphic UI.
- 4 distinct roles — Admin, HR Officer, Payroll Officer, Employee
- JWT-based authentication with argon2 password hashing
- Role-specific dashboards, navigation, and permissions
- Automated welcome emails with credentials on account creation
- One-click check-in / check-out with live timer
- Re-check-in support after half-day leave
- Calendar heatmap view with color-coded attendance
- Weekly/monthly attendance charts with Recharts
- Apply for leaves with type selection and date range
- HR/Admin approval workflow (approve/reject with notifications)
- Leave balance tracking per type per year
- Searchable employee picker for leave allocation (scales to 1000+ employees)
- Leave allocation by HR with balance enforcement
- Salary structure management (Basic, HRA%, Special Allowance)
- Payrun generation with automatic calculations:
- PF (12% employee + 12% employer)
- Professional Tax (slab-based)
- Unpaid leave deductions (pro-rata)
- PDF payslip generation with detailed breakdown
- Monthly payrun history with finalization workflow
- Admin: Company-wide stats, employee distribution, department breakdown
- HR: Attendance trends, leave utilization, headcount analytics
- Payroll: Salary disbursement, deduction summaries, payrun status
- Employee: Personal attendance graph, leave balance, recent payslips
- Glassmorphic design with radial gradients and mesh backgrounds
- Dark/Light theme toggle with smooth transitions (persisted in localStorage)
- Collapsible sidebar with icon-only mode and hover tooltips
- Micro-animations, hover effects, and responsive layouts
- Real-time notifications via Socket.IO
- Welcome email with credentials on employee creation
- Leave status update emails (approved/rejected)
- Password reset flow with tokenized email links
- Gmail SMTP integration (or Ethereal for development)
- Compliance-grade tracking of sensitive system actions
- Automatic logging for salary modifications, role changes, and leave approvals/rejections
- Each record captures: who performed the action, what action, target entity, timestamp, and IP address
- Admin-only read-only access with filtering (by user, action, date range) and pagination
- Secure — logs are non-editable, non-deletable (except via DB maintenance policy)
empay-hrms/
├── backend/ # Express.js REST API
│ ├── src/
│ │ ├── app.js # Server entry + Socket.IO
│ │ ├── config/db.js # PostgreSQL schema + migrations + seeding
│ │ ├── middleware/ # Auth, RBAC, file upload
│ │ ├── modules/ # Feature modules ↓
│ │ │ ├── auth/ # Login, register, password reset
│ │ │ ├── users/ # CRUD, profile pic upload
│ │ │ ├── attendance/ # Check-in/out, history, stats
│ │ │ ├── leave/ # Requests, allocations, types
│ │ │ ├── payroll/ # Payruns, salary, payslips, PDF
│ │ │ ├── dashboard/ # Role-specific analytics
│ │ │ ├── notifications/ # Real-time alerts
│ │ │ ├── settings/ # Company settings
│ │ │ └── audit/ # Audit log tracking & queries
│ │ └── utils/ # Mailer, email templates
│ ├── uploads/avatars/ # Profile picture storage
│ └── seed-demo-data.js # Demo data seeder
│
└── frontend/ # React SPA (Vite)
└── src/
├── context/ # Auth, Theme, Sidebar state
├── components/ # Layout (Sidebar, Topbar) + shared
└── pages/ # Role-based page modules
├── admin/ # Dashboard, User Mgmt, Settings
├── hr/ # Employees, Attendance, Leaves
├── payroll/ # Payruns, Salary, Approvals
├── employee/ # Dashboard, Attendance, Leaves, Payslips
└── shared/ # Profile
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | React 19, Vite 8 | UI framework + build tool |
| Styling | Tailwind CSS 4 | Utility-first CSS |
| Charts | Recharts | Dashboard analytics |
| Icons | Lucide React | Consistent icon set |
| State | React Context | Auth, theme, sidebar |
| Routing | React Router 7 | Client-side navigation |
| Backend | Express.js 4 | REST API server |
| Database | PostgreSQL 14+ | Relational data store |
| Auth | JWT + argon2 | Stateless authentication |
| Real-time | Socket.IO | Live notifications |
| Nodemailer | SMTP email delivery | |
| File Upload | Multer | Avatar image handling |
| PDFKit | Server-side payslip generation |
This project is part of GSSoC '26 (GirlScript Summer of Code 2026). We welcome contributions from developers of all skill levels!
Please read our Contributing Guide before getting started. Check our Roadmap for what needs to be built.
New to open source? Start here: View Good First Issues
We label beginner-friendly issues so you can find tasks that match your skill level. Each good first issue includes:
- Clear task description
- Files to modify
- Acceptance criteria
- Hints to get started
Important
Registration Status: EmPay HRMS is currently pending official registration for GSSoC '26.
The automated bot will not track your points immediately. However, once our application is approved, the tracker will retroactively scan all merged PRs that have the correct tracking labels.
Continue contributing as normal! We (maintainers) will ensure your PRs are properly labeled (GSSoC, level X, etc.) so you get full points when the repo goes live.
See gssoc.girlscript.org for details.
Optional environment setup:
cp .env.example .envStart the full stack:
docker compose up --buildOpen http://localhost:5173. The backend API runs on http://localhost:5000.
PostgreSQL data persists in a Docker volume, and the backend automatically creates tables and seeds demo users on first startup.
To seed full demo dashboard data:
docker compose exec backend node seed-demo-data.jsFor Docker details, see DOCKER.md.
- Node.js 22+ → nodejs.org
- PostgreSQL 14+ → postgresql.org
git clone https://github.com/rushikesh-bobade/empay-hrms.git
cd empay-hrms
# Backend
cd backend && npm install
# Frontend
cd ../frontend && npm installCREATE DATABASE empay_db;Create backend/.env:
PORT=5000
DATABASE_URL=postgresql://postgres:YOUR_PASSWORD@localhost:5432/empay_db
JWT_SECRET=your_super_secret_jwt_key_here
JWT_EXPIRES_IN=7d
# (BCRYPT_ROUNDS is deprecated, using default argon2 config)
FRONTEND_URL=http://localhost:5173
NODE_ENV=developmentcd backend
node src/app.jsnode seed-demo-data.jsThis populates 30 days of attendance, leave allocations, leave requests, salary structures, and 3 months of payroll data.
cd ../frontend
npm run devOpen http://localhost:5173 🎉
| Role | Password | |
|---|---|---|
| 👑 Admin | admin@empay.com |
Password@123 |
| 👩💼 HR Officer | hr@empay.com |
Password@123 |
| 💰 Payroll Officer | payroll@empay.com |
Password@123 |
| 👨💻 Employee | sneha@empay.com |
Password@123 |
| 👨💻 Employee | amit@empay.com |
Password@123 |
| 👨💻 Employee | neha@empay.com |
Password@123 |
| 👨💻 Employee | vikram@empay.com |
Password@123 |
| 👨💻 Employee | ananya@empay.com |
Password@123 |
users ──────────────── 1:N ──── attendance
│ (check_in, check_out, status)
│
├── 1:N ──── leave_requests
│ (type, dates, status, reviewed_by)
│
├── 1:N ──── leave_allocations
│ (type, allocated_days, used_days, year)
│
├── 1:1 ──── salary_structures
│ (basic, hra%, special_allowance)
│
├── 1:N ──── payslips ──── N:1 ──── payruns
│ (gross, deductions, net_pay) (month, year, status)
│
├── 1:N ──── notifications
│ (title, message, is_read)
│
└── 1:N ──── audit_logs
(action, target, metadata, ip_address)
leave_types ──── 1:N ──── leave_requests
1:N ──── leave_allocations
11 tables with full referential integrity, CHECK constraints, and proper indexing.
To send real emails (welcome credentials, leave updates, password reset):
- Enable 2-Step Verification on your Google account
- Generate an App Password
- Add to
backend/.env:
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-gmail@gmail.com
SMTP_PASS=your-16-char-app-password
SMTP_FROM="EmPay HRMS" <your-gmail@gmail.com>Without SMTP config, emails go to Ethereal (test mode) with preview URLs in the console.
Built for the Odoo x Hackathon 🏆 — now open source under GSSoC '26.
This project is licensed under the MIT License.
⭐ Star this repo if you found it useful!
Made with ❤️ for the open-source community