Filipino payroll calculators for JavaScript and PHP — SSS, PhilHealth, Pag-IBIG monthly contributions, 13th-month pay, BIR withholding tax for all four payroll periods (monthly / semi-monthly / weekly / daily, TRAIN brackets), de minimis benefit cap helpers (RR 29-2025), the ₱90,000 13th-month/bonus annual exemption, and pre-tax / post-tax net take-home. Contribution tables are versioned by effective date with source citations.
▶ Try the live demo: ph-payroll-demo.vercel.app — single-page calculator wired to this package.
Sibling of ph-dev-utils and ph-faker.
This package handles real money math for payroll. Wrong outputs cause underpayment / overpayment that affects employees' actual paychecks and remittances to government agencies.
- Verify outputs against an official source (SSS / PhilHealth / Pag-IBIG / BIR circulars, or the agencies' own calculators) before using in production payroll.
- Pin your dependency version. Tables change every few years. A
^0.2floating range will pull in newer tables silently; pin to0.2.xor use a specific tag. - BIR withholding tax operates on taxable income (gross − mandatories − non-taxable allowances), not raw gross. All four payroll periods (monthly / semi-monthly / weekly / daily) shipped as of v0.3. In
netTakeHome, WT is still opt-in via{ includeWT: true }so the v0.1 default shape is preserved. - De minimis caps are applied per BIR RR 29-2025 (effective 2025-12-22). The helpers (
deMinimisMonthly,deMinimisAnnual) return the non-taxable portion you can feed intotaxableIncome*— caps cannot offset across categories. - No warranty. MIT license. Use at your own risk.
If you spot a discrepancy against an official agency calculator or a real payslip, please file an issue with the example — corrections ship faster than you'd think.
# JavaScript / TypeScript
npm install @ph-dev-utils/payroll
# PHP
composer require phdevutils/payrollRequires Node 20+ or PHP 8.2+.
JS:
import {
netTakeHome,
withholdingTaxMonthly, withholdingTaxSemiMonthly, withholdingTaxWeekly, withholdingTaxDaily,
deMinimisMonthly, deMinimisAnnual,
annualExemption90k,
} from '@ph-dev-utils/payroll';
// Pre-tax (v0.1 default shape — unchanged):
netTakeHome(30000);
// { gross: 30000, totalDeductions: 2450, net: 27550, ... }
// Monthly with BIR WT (v0.2+ opt-in):
netTakeHome(30000, { includeWT: true });
// { ..., net: 27550, taxableIncome: 27550, withholdingTax: 1007.55, netAfterTax: 26542.45 }
// Per-period WT (v0.3) — caller supplies taxable income per cutoff:
withholdingTaxSemiMonthly(13775); // { wt: 503.7, bracket: 2, period: 'semi-monthly', ... }
withholdingTaxWeekly(6500); // { wt: 253.8, ... }
withholdingTaxDaily(1200); // { wt: 82.45, ... }
// De minimis caps (v0.3) — pre-cap before passing to nonTaxableAllowances:
const dm = deMinimisMonthly({ riceSubsidy: 2500, laundryAllowance: 400 });
// dm.nonTaxable === 2900 → feed into netTakeHome
netTakeHome(30000, { includeWT: true, nonTaxableAllowances: dm.nonTaxable });
// ₱90k 13th-month + bonus annual exemption (v0.3):
annualExemption90k({ thirteenthMonthPay: 30000, otherBonuses: 100000 });
// { totalReceived: 130000, exempt: 90000, taxableExcess: 40000, cap: 90000, ... }PHP:
use PhDevUtils\Payroll\{TakeHome, WithholdingTax, DeMinimis, AnnualExemption};
$r = TakeHome::netTakeHome(30000, ['includeWT' => true]);
// $r['netAfterTax'] === 26542.45
WithholdingTax::semiMonthly(13775); // ['wt' => 503.7, 'period' => 'semi-monthly', ...]
DeMinimis::monthly(['riceSubsidy' => 2500, 'laundryAllowance' => 400]);
// ['nonTaxable' => 2900.0, 'taxableExcess' => 0.0, ...]
AnnualExemption::ninetyK(['thirteenthMonthPay' => 30000, 'otherBonuses' => 100000]);
// ['exempt' => 90000.0, 'taxableExcess' => 40000.0, ...]See the per-package READMEs for the full API reference:
| Capability | JS | PHP |
|---|---|---|
| SSS contribution | sssContribution(salary) |
Sss::contribution($salary) |
| PhilHealth contribution | philHealthContribution(salary) |
PhilHealth::contribution($salary) |
| Pag-IBIG contribution | pagIbigContribution(salary) |
PagIbig::contribution($salary) |
| 13th-month from total | thirteenthMonthPay(total) |
ThirteenthMonth::fromTotal($total) |
| 13th-month from monthly | thirteenthMonthFromMonthly(monthly, monthsWorked?) |
ThirteenthMonth::fromMonthly($monthly, $months) |
| BIR monthly WT | withholdingTaxMonthly(taxableIncome) |
WithholdingTax::monthly($ti) |
| BIR semi-monthly WT (v0.3) | withholdingTaxSemiMonthly(ti) |
WithholdingTax::semiMonthly($ti) |
| BIR weekly WT (v0.3) | withholdingTaxWeekly(ti) |
WithholdingTax::weekly($ti) |
| BIR daily WT (v0.3) | withholdingTaxDaily(ti) |
WithholdingTax::daily($ti) |
| Taxable income helper | taxableIncomeMonthly(gross, opts?) |
TaxableIncome::monthly($gross, $opts) |
| De minimis (monthly caps) (v0.3) | deMinimisMonthly({ rice, laundry, ... }) |
DeMinimis::monthly([...]) |
| De minimis (annual caps) (v0.3) | deMinimisAnnual({ uniform, medical, ... }) |
DeMinimis::annual([...]) |
| ₱90k annual exemption (v0.3) | annualExemption90k({ thirteenthMonth, otherBonuses }) |
AnnualExemption::ninetyK([...]) |
| Net take-home (pre-tax) | netTakeHome(salary) |
TakeHome::netTakeHome($salary) |
| Net take-home (with WT) | netTakeHome(salary, { includeWT: true }) |
TakeHome::netTakeHome($salary, ['includeWT' => true]) |
| Table | Effective | Source |
|---|---|---|
| SSS (2025+) | 2025-01-01 → present | SSS Circular 2024-006 (RA 11199) |
| PhilHealth 5% (final UHC rate) | 2024-01-01 → present | RA 11223 (Universal Health Care Act) |
| Pag-IBIG (Feb 2024+) | 2024-02-01 → present | HDMF Circular 460 (RA 9679) |
| BIR monthly WT (TRAIN 2023+) | 2023-01-01 → present | BIR RR 11-2018 (RA 10963 / TRAIN, second-phase brackets) |
| BIR semi-monthly / weekly / daily WT | 2023-01-01 → present | BIR RR 11-2018 Annex E (companion tables, same TRAIN brackets) |
| De minimis caps | 2025-12-22 → present | BIR RR 29-2025 (rice ₱2,500/mo, uniform ₱8k/yr, medical ₱12k/yr, etc.) |
| 13th-month + bonus ₱90k exemption | 2018-01-01 → present | RA 10963 § 32(B)(7)(e); reaffirmed by RR 29-2025 |
See data/README.md for full sourcing notes.
- v0.1 ✅ SSS, PhilHealth, Pag-IBIG, 13th month, take-home (pre-tax only)
- v0.2 ✅ BIR monthly withholding tax (TRAIN brackets) + taxable-income helper + opt-in WT in
netTakeHome - v0.3 ✅ Per-period BIR WT (semi-monthly, weekly, daily) + de minimis cap helpers (RR 29-2025) + ₱90k 13th-month/bonus exemption helper
- v0.4+ Form 2316 annualization, year-end reconciliation, OT meal-allowance helper (needs regional minimum wage data); TBD based on user feedback
- OT / night-shift meal allowance (BIR caps at 30% of regional daily minimum wage). The peso amount varies by region; v0.3 lacks the regional wage dataset, so this category is not in
deMinimisMonthly. Compute it yourself or wait for v0.4. - Monetized SL credits / government-employee leave monetization. Only private-sector monetized VL (12-day cap × daily rate) is covered.
- Per-period mandatory-deduction apportionment. SSS / PhilHealth / Pag-IBIG are monthly by rule. For non-monthly payrolls, callers decide how to split mandatories across cutoffs — the library does not impose a policy.
- Pure-WT engine for income types other than compensation income. Business income, professional fees, and other categories use different rules and rates.
Especially valuable PRs:
- New table versions when SSS / PhilHealth / Pag-IBIG / BIR issue updated circulars — include the source PDF or URL.
- Test cases against real published payslips (anonymized).
- Bug reports with concrete inputs that produce wrong outputs.
By contributing, you agree to MIT license.
MIT