Raw phone numbers leaking will ruin your whole day
Source: Dev.to
Introduction
Shipping phone masking sounds trivial… until you meet international formats, weird inputs, and that one QA test with +62 (812)-3456..7890. This TypeScript phone‑masking utility is built for that reality, follows GDPR and data‑protection standards, makes no locale assumptions, accepts strings or numbers, and safely normalizes whatever chaos you throw at it. No country rules, no phone‑metadata databases—just predictable masking that doesn’t fight you.
Default behavior
The default behavior is intentionally boring (in a good way): it masks everything except the last 4 digits.
maskPhone('1234567890')
// ******7890
maskPhone('+62 812 3456 7890')
// +*********7890
You don’t need to configure anything to get sane output—exactly how a utility like this should behave.
Configurable options
When you need control, the API stays flat and readable.
Show a few digits at the front
maskPhone('628123456789', { showFirst: 3, showLast: 2 })
// 628*******89
Preserve formatting for UI display
maskPhone('+1 (555) 123-4567', { preserveFormat: true })
// +* (***) ***-4567
No magic, no surprises. The function does exactly what the options say—nothing more, nothing less.
Custom mask
For the “I know what I’m doing” crowd, customMask overrides everything and gives you full control per character.
maskPhone('1234567890', {
customMask: (char, idx) => (idx % 2 === 0 ? '*' : char),
})
// *2*4*6*8*0
Under the hood
The code stays tiny, dependency‑free, and aggressively defensive:
nullvalues won’t crash it.- Absurd option values won’t leak data.
- Long inputs won’t melt your logs.
It’s the kind of utility you drop into UI, analytics, or logging and then forget about—which is the highest compliment you can give masking code.
Installation
The code lives on GitHub, fully open, zero drama:
Install it with your preferred package manager:
npm install @ekaone/mask-phone
# or
yarn add @ekaone/mask-phone
# or
pnpm add @ekaone/mask-phone
That’s it. No post‑install rituals, no peer‑dependency surprises, and no “why is this 3 MB?”.