Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

india-payroll-rules

Statutory payroll and salary-tax maths for India, as tested JavaScript with zero dependencies — plus the underlying slab data as plain JSON you can use in any language.

FY 2026-27 (AY 2027-28). Income tax under the new regime, gratuity under the 2025 Labour Codes, HRA exemption under Section 10(13A), and professional tax for every state that levies it.

Interactive documentation → — every function with a live playground, the edge cases worked through with real numbers, and the slab data in full. The page runs this package in your browser, so the figures there are the figures the library returns.

npm install india-payroll-rules   # or just copy src/index.js — it has no dependencies
const rules = require("india-payroll-rules");

rules.inHandSalary({ ctc: 1200000 });
// { gross: 1128000, employeePf: 72000, incomeTax: 0, monthlyNet: 87800, ... }

rules.gratuity({ lastDrawnWage: 40000, years: 6, months: 4 });
// { amount: 138462, countedYears: 6, eligible: true, exempt: 138462, taxable: 0 }

rules.professionalTax("karnataka", 30000);
// { monthly: 200, annual: 2400, levied: true, state: "Karnataka" }

Why this exists

These formulas look trivial and are widely implemented wrong. The cases below are the ones we kept finding broken in calculators, spreadsheets and payroll code — each one has a test here.

1. The Section 87A rebate has marginal relief

Under the new regime, tax is nil when taxable income is within ₹12,00,000. Just past it, most implementations jump straight to the full slab figure. The law instead caps the tax at the amount by which you crossed the limit.

Taxable income Naive slab tax Correct tax (with relief + cess)
₹12,00,000 ₹0 ₹0
₹12,41,000 ₹66,150 ₹42,640

2. Gratuity rounds up only above six months

The Payment of Gratuity Act counts a part-year as a full year when service exceeds six months. Exactly six months does not round up — a boundary many calculators get wrong.

rules.gratuity({ lastDrawnWage: 40000, years: 6, months: 6 }).countedYears; // 6
rules.gratuity({ lastDrawnWage: 40000, years: 6, months: 7 }).countedYears; // 7

3. Employers outside the Act use a different divisor

Covered employers (10 or more employees) pay wage × 15/26 × years. Employers outside the Act pay half a month's salary per completed year — 15/30, with no rounding up.

4. The ₹20 lakh gratuity exemption is a lifetime cap

Section 10(10) is cumulative across every employer you ever receive gratuity from, so exemption already used reduces what remains. Government employees are fully exempt.

rules.gratuity({ lastDrawnWage: 500000, years: 30, exemptionAlreadyUsed: 1500000 }).exempt;
// 500000 — not 2000000

5. Professional tax is capped by the Constitution

Article 276 caps professional tax at ₹2,500 per year regardless of what a state's slabs add up to. Tamil Nadu, Kerala and Madhya Pradesh also levy half-yearly or annually rather than monthly, so their "monthly" figures are averages.

6. Fixed-term employees now qualify for gratuity after 1 year

Under the Labour Codes in force from 21 November 2025, fixed-term employees become eligible after one year of service instead of five. The codes also require the wage base to be at least 50% of total pay, which raises gratuity for salary structures built around a small basic.

API

Function Returns
incomeTax(taxableIncome) tax under the new regime incl. 87A relief, surcharge and 4% cess
slabTax(taxableIncome) slab tax alone, before rebate/surcharge/cess
surchargeRate(taxableIncome) 0, 0.10, 0.15 or 0.25
inHandSalary({ ctc, basicPercent, pf, professionalTax }) full CTC → monthly take-home breakdown
gratuity({ lastDrawnWage, years, months, covered, employeeType, exemptionAlreadyUsed }) amount, eligibility, exempt and taxable parts
hraExemption({ basic, da, hraReceived, rentPaid, metro }) exemption plus all three limbs
professionalTax(state, monthlySalary) monthly and annual PT, capped at ₹2,500
statesWithProfessionalTax() list of state slugs

pf accepts "full" (12% of basic), "capped" (₹1,800/month) or "none". employeeType accepts "permanent", "fixedTerm" or "government".

Data

The slab data is plain JSON, usable without the library:

Assumptions in inHandSalary

Stated explicitly because they change the answer: basic is 50% of CTC by default; the employer's PF contribution is treated as part of CTC and the employee contributes the same; professional tax defaults to ₹2,400/year. Gratuity provisions, insurance premiums and variable pay are not modelled — pass the fixed portion of CTC for a realistic monthly figure.

Tests

node --test test/rules.test.js   # 17 tests, no test framework needed

Live calculators

Every rule here is used in production by the free calculators at klair.in, which run entirely in the browser and store nothing:

Accuracy and licence

Cross-checked against the relevant sections and, where states publish them, the notified slabs. Tax law changes and states revise professional tax in their budgets — verify anything you rely on in production, and open an issue if you find a discrepancy. This is not tax advice.

MIT © Klair Technology Solutions

About

Statutory payroll & salary-tax maths for India (FY 2026-27): new-regime income tax with 87A marginal relief, gratuity under the 2025 Labour Codes, HRA exemption, state-wise professional tax. Zero deps, tested, slab data as JSON.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages