// case-study.md

@ph-dev-utils — Filipino Developer Utilities
An open-source family of 12 packages for JS/TS & PHP, with a live in-browser playground

A cohesive family of small, focused packages that ship the Philippine-specific primitives every local app re-implements from scratch — peso formatting, government-ID validation, PSGC address data, ZIP codes, statutory payroll, BIR tax, holidays & Tagalog dates, seedable fake data, and a React address picker. Built with JS ↔ PHP parity so your backend and frontend agree on the same rules, and fronted by a live playground where every demo runs the actual published npm package in the browser — so the showcase doubles as a continuous integration test for the whole family.

project Open source · public on npm & Packagist
last touched
role Author / Maintainer
period 2026 — Present
status Published · live demos
React 19 TypeScript Vite 8 Tailwind CSS npm Packagist (PHP) PSGC data Vercel
// receipts · tl;dr
packages in the family
12
dual-published (npm + Packagist)
11
live in-browser demos
10
barangays in the dataset
42,046
// outcome · what changed
BEFORE

Every PH project re-implements peso formatting, TIN/SSS validation, and PSGC dropdowns from scratch — subtly differently each time.

AFTER

One install — @ph-dev-utils/core — ships the primitives, versioned and validator-checked.

BEFORE

Backend (PHP) and frontend (JS) drift on the same rule — a TIN valid on one side fails on the other.

AFTER

11 of 12 packages publish identical behavior on both npm and Packagist, so the two sides agree by construction.

BEFORE

A library’s README claims it “works” — you only find out at runtime, in your app.

AFTER

The showcase imports and runs every package live in the browser — the demos are the integration test.

What it is

@ph-dev-utils is a family of 12 open-source packages that encode the Philippine-specific logic local apps keep rebuilding: money, government IDs, addresses, payroll, tax, dates, and reference data. Eleven of the twelve ship twice — on npm (@ph-dev-utils/*) for JavaScript/TypeScript and on Packagist (phdevutils/*) for PHP — with deliberately identical behavior so a value validated in a Laravel API is validated the same way in a React form.

The site is two things at once: a landing page that catalogs every package with its version, highlights, and links, and a live playground where ten of the twelve packages run interactively in the browser. Crucially the demos are not mocks — the React app lists the real @ph-dev-utils/* packages as dependencies and calls them directly, so the showcase is also the family’s end-to-end smoke test. Built with React 19, TypeScript, Vite 8 and Tailwind, deployed on Vercel.

The bottleneck

Almost every app built for the Philippine market needs the same primitives, and almost every team re-implements them — usually incompletely, and never the same way twice:

The goal: a single, cohesive, parity-checked family that covers these primitives once, sourced from authoritative data, published on both ecosystems, and demonstrably working — not asserted-working.

How I broke it down

What I built

The 12-package family — grouped by concern:

The parity payoff in one snippet — the same call, the same result, on either runtime:

app/payroll/compute.ts
import { formatPeso, validateTIN, numberToWords } from '@ph-dev-utils/core'
import { netTakeHome } from '@ph-dev-utils/payroll'

formatPeso(1234567.5)             // "₱1,234,567.50"
numberToWords(1042, 'fil')        // "isang libo apatnapu't dalawa"
validateTIN('123-456-789-000')    // { valid: true, formatted: '123-456-789-000' }

// gross → SSS / PhilHealth / Pag-IBIG / BIR withholding → net, in one call
const pay = netTakeHome({ monthlyGross: 45000, period: 'semi-monthly' })
//   → { sss, philhealth, pagibig, withholdingTax, net }

// …and the PHP side agrees, byte-for-byte:
//   use PhDevUtils\Core\Money;
//   Money::formatPeso(1234567.5);   // "₱1,234,567.50"
The @ph-dev-utils playground — a grid of package cards (core, payroll, bir, dates, faker, address-picker, banks, geo, psic, business, postal, psgc-barangays) each with version and npm/Packagist links, beside a live interactive demo panel computing net take-home pay from a gross salary using the real published payroll package.
MOCKLanding + playground · the package grid on the left (12 cards, version + npm/Packagist/GitHub links), a live demo panel on the right running the real published package in the browser. Rendered mock of the public site.

Tech

Results

PSGC barangays
42,046
ZIP / postal codes
2,048
city/municipality coordinates
1,573
banks & e-money institutions
158

The family covers the PH primitives end-to-end: roughly ten government-ID validators, the full PSGC address hierarchy down to 42,046 barangays, 2,048 ZIP codes, 1,573 city/municipality coordinates, 158 banking institutions, and the 21-section / 88-division PSIC classification — plus payroll and tax math that goes gross to net in a single call. Eleven of the twelve packages give a PHP backend and a JS frontend the same answer, removing an entire class of “valid here, invalid there” bugs.

Because the public playground runs the real packages, it is also the family’s smoke test: a breaking change in any published version surfaces as a broken demo on the next deploy, not as a surprise in someone’s production app.

What I’d do again — and differently

Worked well:

Would tighten: