DEV Community

Cover image for Raw phone numbers leaking will ruin your whole day
Eka Prasetia
Eka Prasetia

Posted on

Raw phone numbers leaking will ruin your whole day

"Yooo—quick question. Are you thirsty?
because I’m about to spill some digits… just not all of them."

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, zero locale assumptions, accepts strings or numbers, and safely normalizes whatever chaos you throw at it. No country rules, no phone metadata databases, predictable masking that doesn’t fight you.

The default behavior is intentionally boring (in a good way), mask everything except the last 4 digits.

maskPhone('1234567890')
// ******7890

maskPhone('+62 812 3456 7890')
// +*********7890
Enter fullscreen mode Exit fullscreen mode

You don’t need to configure anything to get sane output, which is exactly how a utility like this should behave.

When you do need control, the API stays flat and readable. Want to expose a few digits at the front? Preserve formatting for UI display?

maskPhone('628123456789', { showFirst: 3, showLast: 2 })
// 628*******89

maskPhone('+1 (555) 123-4567', { preserveFormat: true })
// +* (***) ***-4567
Enter fullscreen mode Exit fullscreen mode

No magic. No surprises. The function does exactly what the options say—nothing more, nothing less.

And for the “I know what I’m doing” crowd, there’s customMask. This option overrides everything and gives you full control per character.

maskPhone('1234567890', {
  customMask: (char, idx) => (idx % 2 === 0 ? '*' : char),
})
// *2*4*6*8*0
Enter fullscreen mode Exit fullscreen mode

Is this something you should do? Maybe not. But when you need it, you’ll be very glad it’s there.

Under the hood, the code stays tiny, dependency-free, and aggressively defensive 👉: nulls won’t crash it, absurd option values won’t leak data, and 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.

Wanna try it? (you know you do 😏)

The code lives here, fully open, zero drama:
👉 GitHub: https://github.com/ekaone/mask-phone

Install it, no judgment here:

npm install @ekaone/mask-phone
# or
yarn add @ekaone/mask-phone
# or
pnpm add @ekaone/mask-phone
Enter fullscreen mode Exit fullscreen mode

That’s it. No post-install rituals, no peer-dependency surprises 😲, no "why is this 3MB?".

Top comments (0)