npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ph-dev-utils/payroll

v0.3.0

Published

Filipino payroll calculators — SSS, PhilHealth, Pag-IBIG, 13th-month, BIR withholding tax for all 4 payroll periods (TRAIN), de minimis caps (RR 29-2025), ₱90k 13th-month/bonus exemption, net take-home. Versioned tables.

Downloads

231

Readme

@ph-dev-utils/payroll

npm version License: MIT Made in PH

Filipino payroll calculators for JavaScript / TypeScript — SSS, PhilHealth, Pag-IBIG monthly contributions, 13th-month pay, BIR monthly withholding tax (TRAIN), and pre-tax / post-tax net take-home. Tables versioned by effective date.

⚠️ READ FIRST

This package handles real money math. Wrong outputs cause underpayment / overpayment in actual payroll runs. Verify outputs against official agency calculators before production use. Pin your dependency version — tables change every few years. BIR WT in v0.2 is monthly-only and operates on taxable income, not raw gross. De minimis caps and the ₱90k 13th-month annual exemption are caller-handled in v0.2.

Full disclaimer: project README.

Install

npm install @ph-dev-utils/payroll

Requires Node 20+.

Quick start

import { netTakeHome } from '@ph-dev-utils/payroll';

netTakeHome(30000);
// pre-tax (v0.1 shape — unchanged):
// {
//   gross: 30000,
//   sss: { msc: 30000, employeeShare: 1500, employerShare: 3030, ... },
//   philHealth: { total: 1500, employee: 750, employer: 750 },
//   pagIbig: { mfs: 10000, employee: 200, employer: 200, total: 400 },
//   totalDeductions: 2450,
//   net: 27550
// }

netTakeHome(30000, { includeWT: true });
// adds: taxableIncome: 27550, withholdingTax: 1007.55, netAfterTax: 26542.45

API Reference

sssContribution(monthlyCompensation, opts?)

Source: SSS Circular 2024-006 (effective 2025-01-01, applies to 2025–2026).

function sssContribution(
  monthlyCompensation: number,
  opts?: { year?: number }
): SSSContribution

interface SSSContribution {
  msc: number;                                          // Monthly Salary Credit (₱500 increments, clamped 5,000–35,000)
  regular: { employee: number; employer: number; total: number };  // MSC capped at 20,000
  mpf:     { employee: number; employer: number; total: number };  // MySSS Pension Booster — portion above 20,000
  ec: number;                                           // Employees' Compensation (employer-paid)
  employeeShare: number;                                // regular.employee + mpf.employee
  employerShare: number;                                // regular.employer + mpf.employer + ec
  total: number;
}

Math: Total rate 15% = 10% employer + 5% employee. EC is ₱10 if MSC ≤ 14,500, ₱30 if MSC ≥ 15,000.

sssContribution(20000);
// { msc: 20000, regular: { employee: 1000, employer: 2000, total: 3000 },
//   mpf: { employee: 0, employer: 0, total: 0 }, ec: 30,
//   employeeShare: 1000, employerShare: 2030, total: 3030 }

sssContribution(30000);
// MPF kicks in: regular at MSC=20k, MPF at MSC=10k
// { msc: 30000, regular: { employee: 1000, ... }, mpf: { employee: 500, employer: 1000, total: 1500 },
//   ec: 30, employeeShare: 1500, employerShare: 3030, total: 4530 }

sssContribution(50000).msc;   // 35000 (capped at MSC max)
sssContribution(3000).msc;    // 5000 (floored at MSC min)

philHealthContribution(monthlySalary, opts?)

Source: RA 11223 (UHC Law) final 5% rate (applies 2024+; no further increases scheduled).

function philHealthContribution(
  monthlySalary: number,
  opts?: { year?: number }
): { total: number; employee: number; employer: number }

Math: 5% of monthly salary, split equally (2.5% each). Floor ₱500 total (salary ≤ ₱10,000). Cap ₱5,000 total (salary ≥ ₱100,000). Each share is rounded to the centavo; the remitted total is the sum of remitted shares (real-payroll convention).

philHealthContribution(25000);     // { total: 1250, employee: 625, employer: 625 }
philHealthContribution(5000);      // floor: { total: 500, employee: 250, employer: 250 }
philHealthContribution(150000);    // ceiling: { total: 5000, employee: 2500, employer: 2500 }

pagIbigContribution(monthlySalary, opts?)

Source: HDMF Circular 460 (effective 2024-02-01). MFS ceiling raised from ₱5,000 to ₱10,000 in Feb 2024.

function pagIbigContribution(
  monthlySalary: number,
  opts?: { year?: number }
): { mfs: number; employee: number; employer: number; total: number }

Math:

  • MFS = min(monthlySalary, 10,000)
  • If MFS ≤ ₱1,500: employee 1%, employer 2%
  • If MFS > ₱1,500: employee 2%, employer 2%
  • Max ₱200 each side (at MFS = ₱10,000)

Mandatory contribution only. Voluntary higher contributions are not computed here.

pagIbigContribution(1000);      // low bracket: { mfs: 1000, employee: 10, employer: 20, total: 30 }
pagIbigContribution(5000);      // high bracket: { mfs: 5000, employee: 100, employer: 100, total: 200 }
pagIbigContribution(50000);     // MFS capped: { mfs: 10000, employee: 200, employer: 200, total: 400 }

thirteenthMonthPay(totalBasicEarnings) / thirteenthMonthFromMonthly(monthlyBasicSalary, monthsWorked?)

Source: PD 851 (Presidential Decree on 13th-month pay).

function thirteenthMonthPay(totalBasicEarnings: number): number
function thirteenthMonthFromMonthly(monthlyBasicSalary: number, monthsWorked?: number): number

Math: DOLE canonical formula is totalBasicEarnings / 12. The "proration" for partial-year employees is captured by passing actual earnings — not by post-multiplying.

thirteenthMonthFromMonthly is a convenience for fixed-salary employees: equivalent to thirteenthMonthPay(monthlyBasicSalary × monthsWorked).

"Basic earnings" excludes allowances, overtime, holiday pay, night-shift differential, and other non-base monetary benefits. Caller is responsible for passing the right figure.

thirteenthMonthPay(360000);              // 30000 (full year @ 30k/month)
thirteenthMonthPay(180000);              // 15000 (6 months @ 30k/month)
thirteenthMonthFromMonthly(30000);       // 30000 (defaults to 12 months)
thirteenthMonthFromMonthly(30000, 6);    // 15000
thirteenthMonthFromMonthly(30000, 1);    // 2500

withholdingTaxMonthly(taxableIncome, opts?) (v0.2+)

Source: BIR RR 11-2018 monthly table (TRAIN Law, second-phase rates effective 2023-01-01).

function withholdingTaxMonthly(
  taxableIncome: number,
  opts?: { year?: number }
): { wt: number; bracket: 1|2|3|4|5|6; marginalRate: number }

Input is taxable income, not gross. To derive taxable income from gross, use taxableIncomeMonthly (or compute manually as gross − mandatories − nonTaxableAllowances).

BIR monthly brackets (TRAIN 2023+):

| Bracket | Monthly taxable income | Tax | | --- | --- | --- | | 1 | ≤ ₱20,833 | 0 | | 2 | ₱20,833 – ₱33,333 | 15% of excess over ₱20,833 | | 3 | ₱33,333 – ₱66,667 | ₱1,875 + 20% of excess over ₱33,333 | | 4 | ₱66,667 – ₱166,667 | ₱8,541.80 + 25% of excess over ₱66,667 | | 5 | ₱166,667 – ₱666,667 | ₱33,541.80 + 30% of excess over ₱166,667 | | 6 | > ₱666,667 | ₱183,541.80 + 35% of excess over ₱666,667 |

withholdingTaxMonthly(15000);    // { wt: 0,         bracket: 1, marginalRate: 0    }
withholdingTaxMonthly(25000);    // { wt: 625.05,    bracket: 2, marginalRate: 0.15 }
withholdingTaxMonthly(50000);    // { wt: 5208.4,    bracket: 3, marginalRate: 0.20 }
withholdingTaxMonthly(100000);   // { wt: 16875.05,  bracket: 4, marginalRate: 0.25 }
withholdingTaxMonthly(200000);   // { wt: 43541.7,   bracket: 5, marginalRate: 0.30 }
withholdingTaxMonthly(1000000);  // { wt: 300208.35, bracket: 6, marginalRate: 0.35 }

taxableIncomeMonthly(gross, opts?) (v0.2+)

Derive monthly taxable income from gross. Formula:

taxableIncome = gross − mandatoryDeductions − nonTaxableAllowances
function taxableIncomeMonthly(
  gross: number,
  opts?: {
    year?: number;
    mandatoryDeductions?: number;   // override SSS+PH+Pag-IBIG; default: auto-computed
    nonTaxableAllowances?: number;  // de minimis within caps + tax-exempt allowances; default: 0
  }
): number

Caller-handled (not done here):

  • De minimis caps — pass only the non-taxable portion of each benefit. Rice subsidy is exempt up to ₱2,000/mo, uniform ₱6,000/yr, medical ₱10,000/yr (employee), etc. If a benefit exceeds its cap, the excess is taxable and should NOT appear in nonTaxableAllowances.
  • 13th-month / bonus ₱90k annual exemption — applies at year level, not month. Excess goes in gross for the month received.
taxableIncomeMonthly(30000);                                  // 27550 (auto: gross − 2,450 mandatories − 0)
taxableIncomeMonthly(30000, { nonTaxableAllowances: 2000 });  // 25550
taxableIncomeMonthly(50000, { mandatoryDeductions: 3200 });   // 46800

netTakeHome(monthlySalary, opts?)

Net take-home: gross salary minus mandatory SSS / PhilHealth / Pag-IBIG employee contributions, and (optionally, v0.2+) BIR withholding tax.

function netTakeHome(
  monthlySalary: number,
  opts?: {
    year?: number;
    includeWT?: boolean;            // v0.2+: also compute WT and netAfterTax
    nonTaxableAllowances?: number;  // v0.2+: only used when includeWT is true
  }
): NetTakeHome

interface NetTakeHome {
  gross: number;
  sss: SSSContribution;
  philHealth: PhilHealthContribution;
  pagIbig: PagIbigContribution;
  totalDeductions: number;          // sum of employee shares
  net: number;                      // gross - totalDeductions (pre-tax)
  taxableIncome?: number;           // populated only when includeWT
  withholdingTax?: number;          // populated only when includeWT
  netAfterTax?: number;             // populated only when includeWT
}

By default (no includeWT), this preserves the v0.1 pre-tax shape. The includeWT: true opt-in adds three fields without removing any.

// v0.1 shape (default) — pre-tax:
netTakeHome(30000).net;        // 27550
netTakeHome(8000).net;         // 7190
netTakeHome(150000).net;       // 145550

// v0.2+ with WT:
netTakeHome(30000, { includeWT: true }).withholdingTax;   // 1007.55
netTakeHome(30000, { includeWT: true }).netAfterTax;      // 26542.45

// v0.2+ with non-taxable allowances:
netTakeHome(30000, { includeWT: true, nonTaxableAllowances: 2000 }).withholdingTax;
// 707.55 (lower because TI dropped from 27,550 → 25,550)

Versioning & rate changes

Tables change. The package follows this contract:

  • Within a major+minor version (e.g. 0.1.x), tables won't change.
  • A new table ships in a new minor version (0.2.0).
  • Old tables stay accessible via the { year } option until a major version cleanup.

Pin your dependency to a specific minor (~0.1.0 or 0.1.x) to avoid silent table changes during your payroll cycle.

When a circular drops, file an issue with the source link — patches ship quickly.

License

MIT