Rupesh N. Chavan SaaS Platform / AI-native HRMS 2026

Six systems
pretending to be one

The average company runs 6.17 HR systems across one employee lifecycle. Emplora collapses that into a single employee record, wraps it in a copilot that finishes the work rather than suggesting it, and publishes the price. For the 50-500 companies that have outgrown BambooHR and can't justify Rippling.

Emplora · Web · interface
RoleProduct Design & Build
Timeline2026
CategoryB2B SaaS / HR Tech
StackNext.js 15 · React 19 · Supabase · Claude
73
Avg. tenure
Months, across all staff
Attrition risk
Lakshmi Krishnan, Stalled progression
1
System, down from 6.17
14
Product modules
4
Roles, one permission matrix
$6 PEPM
Published, no seat floor
The problem
Companies of 50-500 outgrow BambooHR but can't absorb Rippling's $60-80 PEPM. They resolve it by bolting on point solutions, which is exactly how a company ends up running six systems that disagree with each other.
The approach
One employee record every module writes to, an AI layer that completes tasks rather than recommending them, explainable risk scoring, and authorisation enforced in the database instead of in app code.
The outcome
A running multi-tenant SaaS platform, fourteen modules, four roles, predictive analytics, with a published price and a live demo you can open without a sales call.
1
Employee record
18
RLS policy checks
60+
Days of risk warning
0
Sales calls required
Research Insights

The market isn't short
on HR features

It is short on HR systems people actually use. 82% of deployments report adoption challenges while 45% of HR leaders lose over half their week to admin, which means the category competes on time-to-value and interface quality, not on module count. Everyone already has the modules.

Plot the eight platforms that matter on depth against self-serve time-to-value and one quadrant is empty. Darwinbox has enterprise depth but needs a sales cycle. BambooHR has the ease but hits a ceiling. Nobody occupies both corners at once.

That gap has a name and a size: the 50-500 graduation gap, where companies resolve their needs by accumulating point solutions. Emplora attacks it with four wedges. One record, agents that close the loop, mobile parity, and a published all-in price.

01 / 04
Frankensystems are the default
6.17 providers per employee lifecycle, and 77% of organisations splitting people data across multiple HCM databases. The consequence isn't inefficiency, it's blindness. Data that lives apart cannot be correlated, so risk only surfaces after it has cost money.
02 / 04
"AI" currently means a chatbot
What ships in the SMB tier is a conversational layer glued to a help-centre index. The shift buyers have named explicitly is that suggestions do not reduce workload. Execution does. Nobody in this tier ships agents that complete a task end to end.
03 / 04
Everyone builds for the HR admin
Managers are the largest user population and the worst served, which is precisely where the 82% adoption failure concentrates. An episodic user who relearns the interface every time is not a training problem; it is a structural design failure.
04 / 04
Price opacity is the loudest complaint
The most consistent grievance across every review source. Sticker prices understate true cost by 30-50% once add-ons land, and BambooHR carries a $250/month floor. In a category built on quote-gating, a published all-in price is a marketing asset, not just a policy.
The Problem
The Opportunity
One Data Model Agentic AI Explainable Risk Multi-tenant RLS Published Pricing
05 · User Stories

What Users Need

Drawn from five personas, two of whom sign the contract and three of whom live in the product. Every story traces to a shipped module.

As a... I want to... So that... Priority
HR Manager (Priya) See who is likely to resign, and why, before they do I get a 60-day window to act instead of a notice period to react to High
HR Manager (Priya) Have every module read and write the same employee record Monday morning reconciliation stops existing as a task High
Line Manager (Marcus) Receive a review already drafted from goals, 1:1s and peer feedback I'm editing evidence rather than authoring from a blank page on a Sunday High
Line Manager (Marcus) Reach any screen or person by typing what I want Six months between logins doesn't mean relearning the navigation High
COO (David) Import our entire roster from the spreadsheet we already have Time-to-first-value is a day, not a 90-day implementation project High
CHRO (Sarah) See the reasoning behind every AI output, with its sources I can defend the call to the employee it's about, otherwise I can't act on it High
CHRO (Sarah) Detect compensation drift against band before it becomes a claim Equity is something I can evidence rather than assert Medium
Employee (Aisha) Ask a plain-language question and get an answer with a source I don't file a ticket to learn my own leave balance Medium
06 · Competitor Analysis

The Market

Parity on the table stakes is assumed. The rows that decide anything are the bottom five.

Capability BambooHR Rippling Darwinbox Zoho Emplora
Core HRIS & directory ✓ ✓ ✓ ✓ ✓
Integrated payroll Add-on ✓ ✓ Add-on ✓
People analytics Basic ✓ ✓ Basic Predictive
Attrition risk scoring , , ✓ , Explainable
Agentic task execution , Partial Partial , Core
Natural-language command bar , , , , ✓
Mobile capability parity , , ✓ , ✓
Published all-in price , , , ✓ ✓
Seat floor $250/mo Yes Yes None None
Key Design Decisions

How we decided

Five decisions, each one a fork where the conventional answer was available and cheaper. Together they are the product.

Decision 01
Integrate the stack vs. make the second system unnecessary
Option A, Rejected. Build first-rate integrations. Sync employee data between the ATS, the payroll provider, the performance tool and the LMS. This is what the category does, and it is what buyers ask for.
Option B, Chosen. One employee entity that every module reads and writes. Nothing owns a private copy. Profile, employment, compensation, timeline, time off, performance, documents, training and risk signals all hang off the same row.
Reasoning
Integration makes the fragmentation survivable; it doesn't remove it. Two synced databases are still two databases, and the sync itself becomes the thing that breaks, which is why systems integration ranks second among HR pain points. More importantly, correlation is impossible across a sync boundary: you cannot score attrition risk from engagement, comp position and progression unless those three live in one place. The single record is not a tidiness preference, it is the precondition for every predictive feature in the product.

Integration makes the fragmentation survivable; it doesn't remove it. Two synced databases are still two databases, and the sync itself becomes the thing that breaks, which is why systems integration ranks second among HR pain points. More importantly, correlation is impossible across a sync boundary: you cannot score attrition risk from engagement, comp position and progression unless those three live in one place. The single record is not a tidiness preference, it is the precondition for every predictive feature in the product.
Decision 02
AI that recommends vs. AI that completes the task
Option A, Rejected. A conversational assistant that answers questions and suggests next steps. Low risk, easy to scope, and what every competitor means when they say "AI-powered".
Option B, Chosen. Copilot drafts the retention plan, generates the role-specific 30-day onboarding plan, writes the review from real signals, and files the leave, then asks for one approval.
Reasoning
A recommendation transfers work to the user with extra steps: read it, decide about it, then do the thing anyway. Priya's problem is not that she lacks ideas about retention, it is that she has no hours. The design consequence is that approval, not conversation, becomes the primary interaction: every agent output has to arrive in a reviewable, editable state rather than as a chat message. Editing beats authoring, which is also why Marcus finally submits reviews on time.

A recommendation transfers work to the user with extra steps: read it, decide about it, then do the thing anyway. Priya's problem is not that she lacks ideas about retention, it is that she has no hours. The design consequence is that approval, not conversation, becomes the primary interaction: every agent output has to arrive in a reviewable, editable state rather than as a chat message. Editing beats authoring, which is also why Marcus finally submits reviews on time.
Decision 03
A risk score vs. a score plus its factors
Option A, Rejected. A single tuned number per person, "Kabir Sen: 41% flight risk". Cleaner in the interface, and it allows a more sophisticated model behind it.
Option B, Chosen. The score is the sum of its factors, and every factor carries the sentence that justifies it: "engagement at 48, below the team baseline", "paid 14% under midpoint for band", "4.2 years in role without a level change".
Reasoning
Sarah put it plainly: if she can't explain why the system flagged someone, she can't act on it. A black-box score about a real person is unusable regardless of accuracy, because the next step is always a conversation with a human being who deserves a reason. Making the score additive by construction constrained the model, but it made the output defensible, which is the only property that matters here. One detail proved the point: bands are derived from job-title peer medians, not from the person's own salary. Deriving them from the individual pegs everyone at the 50th percentile and silently zeroes out the comp-equity signal entirely.

Sarah put it plainly: if she can't explain why the system flagged someone, she can't act on it. A black-box score about a real person is unusable regardless of accuracy, because the next step is always a conversation with a human being who deserves a reason. Making the score additive by construction constrained the model, but it made the output defensible, which is the only property that matters here. One detail proved the point: bands are derived from job-title peer medians, not from the person's own salary. Deriving them from the individual pegs everyone at the 50th percentile and silently zeroes out the comp-equity signal entirely.
Decision 04
Authorisation in application code vs. in the database
Option A, Rejected. Guard every API route with permission checks and scope every query by organisation in the repository layer. Conventional, readable, and entirely adequate. Until someone writes a query that forgets.
Option B, Chosen. Row-level security policies in Postgres. Every row is scoped by org_id at the database, salary and engagement are stripped server-side before serialisation, and one isomorphic permission matrix is imported by both the API that enforces and the UI that hides.
Reasoning
This is a multi-tenant product holding salaries. A query this codebase never wrote still must not be able to leak another company's roster, and application-level checks can only protect the queries someone remembered to protect. The design consequence is more interesting than the security one: because scope is enforced below the UI, the interface can render "Restricted" honestly rather than showing a wrong total. A manager sees their reports' salaries and null for everyone else. The directory stays open to all, because an org chart that only shows you yourself is useless.

This is a multi-tenant product holding salaries. A query this codebase never wrote still must not be able to leak another company's roster, and application-level checks can only protect the queries someone remembered to protect. The design consequence is more interesting than the security one: because scope is enforced below the UI, the interface can render "Restricted" honestly rather than showing a wrong total. A manager sees their reports' salaries and null for everyone else. The directory stays open to all, because an org chart that only shows you yourself is useless.
Decision 05
Role-gated routes vs. a role-adaptive dashboard
Option A, Rejected. Separate home routes per role, /hr, /manager, /me. Explicit, easy to reason about, and each one optimisable in isolation.
Option B, Chosen. One /dashboard route with three compositions. HR sees org metrics, status and risk; a manager sees team to-dos, approvals and pulse; an employee sees their balance, tasks and team.
Reasoning
Role-gated routes make a promotion into a navigation change: Marcus becomes a director and the URL he had bookmarked is now the wrong one. Role-adaptive means what he sees changes without where he goes changing, which matters disproportionately for someone who logs in twice a year and is running on stale muscle memory. It also keeps the IA shallow, which was the third rule the architecture had to satisfy: depth capped at three levels, and every node reachable by typing.

Role-gated routes make a promotion into a navigation change: Marcus becomes a director and the URL he had bookmarked is now the wrong one. Role-adaptive means what he sees changes without where he goes changing, which matters disproportionately for someone who logs in twice a year and is running on stale muscle memory. It also keeps the IA shallow, which was the third rule the architecture had to satisfy: depth capped at three levels, and every node reachable by typing.
Final Design

Fourteen modules,
one record

Navigation is organised by employee lifecycle rather than by internal department. Main, Employee Lifecycle, Administration, because that is how all five personas describe their own work. Every screen is a lens onto the same entity; changing route changes the view, never the source.

Three things arrived after this was first written. Compensation Review, which reads the salary bands and shows where a person sits against their own, so a pay conversation starts from the same number on both sides of the table. A notifications feed, because the bell in the header had been promising one for months. And a demo reset, so a visitor can change anything in the live demo without permanently breaking it for whoever opens it next.

emplora-hrms.vercel.app/dashboard
Emplora dashboard · headcount, presence, absence, employee status table, department donut and attrition risk

Dashboard, role-adaptive home, captured from the live demo tenant. Metrics count up with tabular numerals so the animation causes no layout shift; the donut draws its arcs on entry. The attrition card names one person and offers "Ask Copilot why" rather than reporting a distribution.

Analytics · headcount over time, flight risks, average tenure and the attrition risk register
Employee record · details, skills, performance, engagement and direct reports
Emplora Copilot panel with suggested questions grounded in the workspace

Analytics leads with "forward-looking workforce intelligence, not last quarter's headcount report", and every figure is derived from the same rows the directory reads. The record is one entity behind tabs; Copilot opens as a right drawer over any screen.

Interactive org chart, canvas view with search
Bulk import · template download, drop zone and recent import history with added/updated/skipped counts
⌘K command palette searching for leave, with an Ask Copilot fallthrough

Import states its contract on the screen, "nothing is written until you review the preview", matched on Employee ID then Email, and every batch is kept with its added, updated and skipped counts. ⌘K reaches pages and people, then falls through to Copilot.

Design Decisions

The five things
that carry it

Extracted from Figma through the MCP server rather than transcribed by eye, and built on Untitled UI primitives. The values below are the real tokens in globals.css, consumed through Tailwind v4's theme layer.

Accessibility baseline: body text meets WCAG AA, focus is visible on every interactive element, status is never encoded by colour alone, charts expose an accessible table equivalent, and ⌘K is reachable from anywhere with Esc closing every overlay.

Colour Tokens
--success-500 (Primary) #17B26A
--success-600 (Hover) #079455
--gray-900 (Primary text) #181D27
--gray-600 (Body) #535862
--gray-200 (Borders) #E9EAEB
--blue-500 (Informational) #2E90FA
--warning-500 (At risk) #F79009
--rose-500 (Critical) #F63D68
--brand-600 (Performance) #7F56D9
Roles & Read Scope
Owner, all HR Admin, all Manager, team Employee, own Restricted
Layout & Elevation
Sidebar / tablet rail 252px / 72px
Topbar height 80px
Grid columns 4 / 2 / 1
Corner radii 8 / 12 / 16 / 20 / 28
Button ring xs-skeuomorphic
Motion, informational, not decorative
Nav pill (shared layoutId) spring 300 / 30
Donut draw 800ms, 60ms stagger
Metric count-up 900ms, tabular nums
Command palette scale .96→1, blur 8px
prefers-reduced-motion honoured globally
Type Scale, Inter, self-hosted
36 / 44 · 700 display-md, landing hero
24 / 32 · 600 display-xs, page titles & metric values
16 / 24 · 600 text-md-semibold, card titles, active nav
14 / 20 · 500 text-sm-medium, table cells and labels
12 / 18 · 600 TEXT-XS-SEMIBOLD, BADGES

One employee record

Problem
Hiring, performance, engagement and compensation living apart makes correlation impossible, so risk is only visible in hindsight.
Approach
A single entity with profile, employment, compensation, append-only timeline, time off, performance, documents, training and risk signals. Every module reads and writes it.
User Benefit
No reconciliation, and no question about which system is right. The record updates as a byproduct of daily work rather than as a data-entry project.
Business Benefit
The metric the product sells against, 6.17 systems per lifecycle down to one, is a structural property rather than a marketing claim.

⌘K · search that falls through to Copilot

Problem
A manager who opens the product twice a year has no memory of the vocabulary, so any hierarchy becomes a memory test he fails.
Approach
A parallel access path to the whole tree, pages and people matched by name, and anything unmatched offered to Copilot as a plain-language question rather than returning "no results".
User Benefit
You never need to know where something lives. Describing what you want is always a valid way to get there.
Business Benefit
Directly targets the manager-adoption failure the research identified as where the category actually loses.

Explainable attrition risk

Problem
Attrition is visible in the data 60-90 days before a resignation, and nobody in this tier surfaces it in a form anyone will act on.
Approach
A weighted, additive score, engagement decline, position below band midpoint, stalled progression, performance dip, each returning its own weight and a sentence that justifies it.
User Benefit
HR can defend the flag to the person it concerns, which is the difference between a signal and an actionable one.
Business Benefit
Turns retention from a postmortem into a forecast, the capability the expansion buyer takes to a board.

Bulk import that reports rather than drops

Problem
Migration is why this segment stays on spreadsheets. And the worst failure in an importer is the silent one. A mistyped header quietly losing a salary column.
Approach
xlsx, CSV and JSON, matched on employee ID then email so re-uploading updates instead of duplicating. ~40 header aliases; anything unrecognised is reported, never dropped. Dry-run preview with per-cell errors, then an atomic commit.
User Benefit
You see exactly what will happen before anything is written, and a downloadable template pre-filled with a real roster doubles as a worked example.
Business Benefit
Time-to-first-value drops from 30-90 days to under a day. The objection that decides the deal for the economic buyer.

Read scope separated from read permission

Problem
Lock the directory down and the org chart becomes useless. Leave it open and salaries leak. Most products pick one and live with the cost.
Approach
Everyone can open the directory; salary, band and engagement are stripped server-side for anyone outside their scope. Owner and HR see all, a manager sees their reports, an employee sees their own record.
User Benefit
The interface says "Restricted" instead of quietly showing a wrong total, a number you can't trust is worse than an absent one.
Business Benefit
A single permission matrix imported by both the API and the UI, so a hidden button can never drift into an unguarded endpoint.
Design System

Published variables,
not approximations

One dashboard, three compositions
HR Admin / Owner Org metrics, status, risk, activity
Manager Team to-dos, approvals, pulse
Employee My balance, my tasks, my team
Enterprise Readiness

What breaks
at 1,000 people

An audit I ran on my own product, and the one finding that mattered more than any feature.

The question I set myself after launch was whether this would survive procurement at a company the size of Samsung or Google. The answer came back uncomfortable, and it had nothing to do with AI. Emplora was quietly showing a truncated company.

The roster was fetched whole on every page load, unpaginated. Supabase caps REST responses at 1,000 rows by default and raises no error when it does. So at 1,001 employees the product did not slow down and it did not fail. It displayed the wrong company with complete confidence: headcount short, payroll totals short, branches missing from the org chart, and nothing anywhere saying so.

I reproduced it rather than reasoning about it. A throwaway tenant with 1,200 employees, queried the way the code did: 1,200 rows in the organisation, 1,000 returned, no error raised. Every number on the dashboard is derived from that array, so every number was wrong.

544
Bytes per employee
Measured, not estimated. The unit that makes the rest of the table arithmetic.
1,000
Silent row cap
The default ceiling, crossed without a warning anywhere in the response.
98 MB
Per load at Google scale
180,000 employees down the wire. Disqualifying on its own, before correctness.
0
Errors raised
Which is what made it a correctness bug rather than a performance one.

Paging restored the right answer: the same tenant now returns all 1,200. It also took 3.9 seconds, and that number is its own argument. Fixing the truncation did not fix the design that wants an entire company in the browser so the client can add it up. Aggregates belong in SQL, and that is the next piece of work rather than a thing I am claiming to have finished.

The second half of the audit was less about code. Enterprise buyers do not evaluate AI first: SAML SSO and SCIM provisioning are routinely pass/fail items on the security questionnaire that gates the deal, and automatic deprovisioning gets scrutinised because manual deactivation is a compliance gap auditors ask about directly. The honest consequence is that no amount of AI gets Emplora into Samsung. SSO, SCIM, SOC 2 and data residency do. The AI is what wins the bake-off once procurement has cleared.

Three things I decided not to build, and the reasoning is the point: AI resume screening, performance prediction that ranks individuals, and anything that scores a person without showing its working. Each carries high-risk obligations under the EU AI Act, and each is what a works council vetoes. A feature you can ship is not the same as a feature you can defend in front of an HR director.

What the audit left standing is worth saying plainly, because it is the part that survives comparison with Workday or SuccessFactors. Tenant isolation here is enforced by the database rather than by application code, and compensation privacy is a column privilege rather than a hidden field. Most of the market enforces both in the application layer, where one missing clause leaks a roster. Emplora's database refuses. That is a narrow wedge, but it is a real one, and it only matters once the product can hold a real company.

Most of the P0 list has since been closed. The roster pages and checks its own row count, so a truncated read now fails loudly instead of rendering a short company. The auth endpoints are throttled, because an unthrottled login is a credential-stuffing target and nothing else. Security headers are set at the edge. The salary bands query was running as the caller and swallowing its own error, which meant a permission problem looked like an empty table: it runs as owner now and reports failure instead of quietly returning nothing. What is still open is the honest part, and it is the procurement list rather than the clever one.

Targets & Outcomes

What it's built
to move

Emplora is a design and engineering concept running on demo data, so these are the success metrics the product was designed against. Each with the baseline it is measured from, rather than adoption results from a customer base.

Portfolio work is usually presented as finished. This is more useful, and more honest, as a ledger.

1
System per lifecycle
Baseline 6.17. The single record makes this structural rather than aspirational.
<25%
HR admin time share
Baseline over 50%. Attacked by killing reconciliation and having agents close loops.
>70%
Manager monthly actives
Baseline ~15%. The zero-recall ⌘K path and pre-drafted reviews target exactly this number.
60+ days
Attrition warning lead time
Baseline zero. The signal exists in the data 60-90 days out; nothing in this tier surfaces it.
Being precise about it

What is real,
and what is not

Persisted & permission-scoped
Organisations, users and the full employee record, title, department, manager, status, presence, dates, salary, performance, engagement, skills, plus import batches and an audit log. Multi-tenant in Postgres with RLS.
Derived from those rows, not fixtures
Headcount and hire trends from real start dates, department and role distributions, birthdays, onboarding and offboarding queues, attendance split, salary bands from per-title medians, attrition risk and its factor breakdown, comp-equity outliers, skill coverage and key-person risk.
Still sample content, labelled in the UI
The learning catalogue, document library, calendar events and leave entitlement balances have no table yet; each is isolated in one file, and every screen already takes its data as props. Onboarding and offboarding checklists are local UI state and say so.
Not built
Billing integration, email delivery, file storage for documents, SSO, and the leave-request approval workflow. Presence is a column, but there is no request-and-approve cycle behind it yet.
Verified
18 RLS checks run signed in as real users with the anon key, and 58 end-to-end API checks cover both clients. A deploy checker catches the things that fail quietly. Stale AAAA records, resolvers disagreeing, a missing HTTPS redirect, the demo tenant still reachable.
Shipped surfaces
A live web app at emplora-hrms.vercel.app and an Android build with full capability parity, both from one codebase. Plus a Dockerfile, Caddyfile, systemd unit and deployment runbook.
Key Learnings

What this project taught me

01
Explainability is a design constraint, not a feature
Making the risk score additive by construction meant giving up a more sophisticated model. That felt like a loss until I remembered the output's actual destination: a conversation with a real person about their career. A number nobody can justify is unusable at any accuracy. The constraint improved the interface too. Showing weighted factors gives HR somewhere to start, which a percentage never does.
02
Where authorisation lives changes what the UI can say
Pushing scope into RLS started as a security decision and turned into a design one. Because the server strips salary before serialisation, the interface can render "Restricted" honestly instead of showing a total that quietly excludes rows the viewer can't see. A wrong number presented confidently is worse than a visibly absent one, and only the database is in a position to know the difference.
03
The unit of AI output is a draft, not a message
Once Copilot's job became finishing work rather than answering questions, the chat surface stopped being the important part. What mattered was that every output landed somewhere reviewable and editable, with one approval at the end. Designing for approval rather than conversation is what makes an agent feel like a colleague instead of a search box.
04
Derive the benchmark from the peer group, never the individual
The first version derived salary bands from each person's own salary. Everything worked, nothing errored, and every band position landed at roughly 50%, because a person compared to themselves is always at the midpoint. It silently zeroed out the entire comp-equity signal. The most dangerous bugs in a data product are the ones that return plausible numbers.
05
Pricing is part of the interface
Publishing $6 PEPM with no seat floor on the landing page was a product decision before it was a marketing one. It removes the demo, the quote and the negotiation, which is to say it removes three screens the user would otherwise have to pass through to reach the product. In a category where price opacity is the loudest complaint, transparency is the fastest path to first value.
06
Writing the research down made it enforceable
Four documents, research, discovery, IA, design system, meant later decisions could be checked against earlier reasoning rather than relitigated from memory. When the mobile scope question came up, the answer was already there in the four wedges. Documentation isn't overhead on a solo project; it's the only thing standing in for the colleague who would otherwise ask "why?".
"The research kept pointing at the same thing from different angles: this category is not short on features, it is short on products people will open. That reframed the whole project. The interesting work wasn't designing fourteen modules, it was deciding that the score has to show its factors, that scope belongs in the database, that the assistant's output has to arrive as a draft, and that the price goes on the landing page. None of those are screens. All of them are the reason the screens work. I also learned to distrust numbers that look fine: the salary-band bug returned a perfectly reasonable 50% for everyone, and it took asking why nothing was ever flagged to notice the signal had been silently deleted."
Rupesh Chavan, Product Design & Build
Explore more