munesoftphonex
All packages
Core 344/mo
@munesoft/

phonex

AI-first phone number validation, parsing, formatting, risk detection, and intelligence library for JavaScript and TypeScript. A modern, modular alternative to libphonenumber-js with built-in caching, AI mode, and zero dependencies.

Installation

$ npm install @munesoft/phonex

Documentation

@munesoft/phonex

The AI-first phone number validation, parsing, and intelligence library for JavaScript & TypeScript. Faster, smarter, and more powerful than traditional solutions like libphonenumber-js.

npm version License: MIT TypeScript Zero dependencies


๐Ÿš€ Why Phonex?

Most libraries only parse phone numbers.

Phonex goes further:

  • โ—†โœ… Validate phone numbers (lenient, strict, AI modes)
  • โ—†โœ… Format international & national numbers
  • โ—†โœ… Detect country, carrier, and number type
  • โ—†โœ… Identify spam, fake, and reserved test numbers
  • โ—†โœ… Optimize SMS / WhatsApp / OTP delivery
  • โ—†โœ… Power AI agents with structured phone intelligence
  • โ—†โœ… Zero runtime dependencies, works in Node.js, browsers, and edge runtimes (Cloudflare Workers, Vercel Edge, Deno)

โšก Install

bash
npm install @munesoft/phonex
bash
yarn add @munesoft/phonex
bash
pnpm add @munesoft/phonex

๐Ÿง  One-Line Usage

ts
import phonex from "@munesoft/phonex";

const phone = phonex("+254712345678");

console.log(phone.valid);          // true
console.log(phone.country);        // "KE"
console.log(phone.countryCallingCode); // "254"
console.log(phone.national);       // "712345678"
console.log(phone.international);  // "+254 712 345678"
console.log(phone.e164);           // "+254712345678"
console.log(phone.type);           // "mobile"
console.log(phone.carrier);        // "Safaricom"
console.log(phone.timezone);       // "Africa/Nairobi"
console.log(phone.risk);           // { score: 0, level: "low", flags: [] }

CommonJS works too:

js
const phonex = require("@munesoft/phonex");
phonex("+254712345678");

๐Ÿ”ฅ Features

๐Ÿ“ž Phone Number Validation (Best-in-Class)

Three validation levels for different stages of your funnel:

ts
import { validate } from "@munesoft/phonex/validate";

// Lenient: fast length-based check, ITU-T E.164 compliant.
// Use during signup so you don't reject borderline-valid international numbers.
validate("+254712345678", { level: "lenient" });

// Strict: full per-country regex validation.
// Use for KYC, billing, OTP delivery.
validate("+254712345678", { level: "strict" });

// AI: strict + anomaly detection (sequential digits, low-entropy, test ranges).
// Returns confidence score + list of anomalies. Use for fraud detection.
validate("+254712345678", { level: "ai" });
// โ†’ { valid, possible, confidence: 0.95, anomalies: [], ... }

๐ŸŒ Country Detection

ts
phonex.detect("+447911123456");   // "GB"
phonex.detect("0712345678", { country: "KE" });  // "KE"

๐Ÿ”„ Normalize Phone Numbers

Turn any messy input into clean E.164:

ts
phonex.normalize("07 12-345-678", { country: "KE" });
// "+254712345678"

phonex.normalize("+254 712.345.678");
// "+254712345678"

โšก Format Phone Numbers

ts
const phone = phonex("+254712345678");

phone.formatInternational();  // "+254 712 345678"
phone.formatNational();       // "712345678"
phone.e164;                   // "+254712345678"

๐Ÿง  AI Mode (Perfect for AI Agents & LLMs)

ts
phonex("+254712345678", { ai: true });

Returns LLM-friendly structured data with confidence and reasoning:

json
{
  "valid": true,
  "country": "KE",
  "type": "mobile",
  "carrier": "Safaricom",
  "ai": {
    "confidence": 0.95,
    "reasoning": "identified as KE; type: mobile; carrier: Safaricom; validated against curated metadata for KE",
    "anomalies": []
  }
}

๐Ÿšจ Risk & Spam Detection

Heuristic detection of fake numbers, test ranges, and patterns commonly seen in fraud:

ts
import { risk } from "@munesoft/phonex/risk";

risk("+254000000000");
// { score: 0.9, level: "high", flags: ["all-identical-digits"] }

risk("+12125550100");
// { score: 0.95, level: "high", flags: ["reserved-test-range"] }

risk("+254712345678");
// { score: 0, level: "low", flags: [] }

Detected signals:

  • โ—†Repeated digits (0000000000)
  • โ—†Sequential digits (1234567890, 9876543210)
  • โ—†Reserved test ranges (NANPA 555-01xx, country-specific test prefixes)
  • โ—†Low entropy (only 1โ€“3 unique digits)
  • โ—†Implausible length
  • โ—†Failed strict validation

๐Ÿ“ก Carrier Detection

Curated, accurate carrier mapping for supported regions. Returns null rather than guess for unsupported countries:

ts
phonex.carrier("+254712345678");  // "Safaricom"
phonex.carrier("+254733456789");  // "Airtel Kenya"
phonex.carrier("+2348031234567"); // "MTN Nigeria"
phonex.carrier("+447911123456");  // null (UK carrier prefixes are not stable)

Supported carrier-detection countries: KE, UG, NG, ZA, IN.

๐Ÿงญ Timezone & Region

ts
import { geo } from "@munesoft/phonex";

geo("+254712345678");
// { country: "KE", callingCode: "254", timezone: "Africa/Nairobi", multiTimezone: false }

geo("+14155552671");
// { country: "US", callingCode: "1", timezone: null, multiTimezone: true }

๐Ÿ“ฒ Multi-Channel Detection

Decide whether SMS, WhatsApp, or voice is appropriate for a number:

ts
phonex.channels("+254712345678");
// { sms: true, whatsapp: true, voice: true }

phonex.channels("+442012345678");
// { sms: false, whatsapp: false, voice: true }   // UK landline

phonex.channels("+8613912345678");
// { sms: true, whatsapp: false, voice: true }    // CN: WhatsApp blocked

Pass ai: true for reasoning on each channel.

โœ๏ธ As-You-Type Formatting

Perfect for phone-input UI components:

ts
phonex.input("0", { country: "KE" });          // "0"
phonex.input("0712", { country: "KE" });       // "0712"
phonex.input("0712345678", { country: "KE" }); // "0712 345 678"

phonex.input("4155552671", { country: "US" }); // "415 555 2671"
phonex.input("+254712345678");                 // "+254 712 345 678"

๐Ÿ’ก Smart Suggestions

When a number is malformed, suggest plausible fixes:

ts
phonex.suggest("712345678");
// {
//   input: "712345678",
//   suggestions: [
//     { e164: "+254712345678", country: "KE", confidence: 0.65, reason: "valid as KE national number" },
//     ...
//   ]
// }

๐Ÿ“Š Bulk Processing

Process thousands of numbers with bounded concurrency:

ts
const results = await phonex.batch(numbers, {
  concurrency: 50,
  country: "KE",
  level: "strict",
  continueOnError: true,
});

Or stream them lazily:

ts
for await (const phone of phonex.stream(numbers)) {
  console.log(phone.country, phone.valid);
}

stream() accepts both Iterable and AsyncIterable โ€” works seamlessly with file streams, fetch responses, generators, and database cursors.

๐Ÿ“ˆ Analytics

Aggregate stats over a list of numbers โ€” perfect for CRM data cleaning, KYC reports, or dashboards:

ts
phonex.analytics(numbers);
// {
//   total: 5000,
//   valid: 4823,
//   invalid: 177,
//   countryDistribution: { KE: 3200, NG: 1100, US: 523 },
//   typeDistribution: { mobile: 4500, landline: 323, voip: 0, tollfree: 0, unknown: 177 },
//   riskDistribution: { low: 4823, medium: 0, high: 177 },
//   topCarriers: [{ carrier: "Safaricom", count: 2400 }, ...]
// }

๐Ÿ”Œ Express Middleware

Auto-validate and normalize phone fields in every request:

ts
import express from "express";
import phonex from "@munesoft/phonex";

const app = express();
app.use(express.json());

app.use(phonex.middleware({
  fields: ["phone", "mobileNumber"],   // fields to scan in body/query/params
  country: "KE",                        // default country
  level: "strict",
  reject: true,                         // 400 on invalid; default false
  normalize: true,                      // rewrite valid fields to E.164
}));

app.post("/signup", (req, res) => {
  // req.body.phone is now "+254712345678" (normalized)
  // req._phonex.phone holds the full PhonexResult
  res.json({ ok: true, phone: req.body.phone });
});

Works with any framework using the standard (req, res, next) signature: Express, Connect, Restify, Polka.

๐Ÿ” Privacy Mode

Mask or hash numbers for logging and storage:

ts
phonex("+254712345678", { privacy: true });
// e164: "+********5678"

phonex("+254712345678", { privacy: "hash" });
// e164: "phx_a1b2c3d4"     // deterministic hash

Note: privacy: "hash" uses FNV-1a โ€” fast and great for deduplication keys, but not cryptographic. For GDPR / regulatory hashing, use Web Crypto SubtleCrypto.digest in your application layer.

๐Ÿงต Streaming Support

ts
for await (const phone of phonex.stream(asyncIterable)) {
  // process one at a time
}

๐Ÿงฉ Plugin System

Extend Phonex with custom logic โ€” third-party data, alternate validation rules, audit logging:

ts
phonex.use({
  name: "twilio-lookup-enrichment",
  onResult(result) {
    // mutate or replace the result
    return result;
  },
});

โš™๏ธ Modular Usage (Tree-Shaking)

Phonex ships with subpath exports so you only pay for what you use:

ts
import { validate } from "@munesoft/phonex/validate";
import { risk } from "@munesoft/phonex/risk";
import { input, suggest, normalize } from "@munesoft/phonex/input";
import { analytics } from "@munesoft/phonex/analytics";
import { middleware } from "@munesoft/phonex/middleware";
import { phonex, parse } from "@munesoft/phonex/core";

Modern bundlers (Vite, esbuild, Rollup, Webpack 5, Parcel 2) will tree-shake unused features automatically. The full bundle is ~40 KB minified before tree-shaking; a typical app importing only validate is well under 20 KB.


๐ŸŒ Universal Compatibility

Phonex runs everywhere modern JS runs:

| Runtime | Supported | |---|---| | Node.js โ‰ฅ 16 | โœ… | | Modern browsers (ES2020) | โœ… | | Cloudflare Workers | โœ… | | Vercel Edge Runtime | โœ… | | Deno | โœ… | | Bun | โœ… |

No Buffer, no fs, no crypto.randomBytes โ€” Phonex is pure JavaScript with zero runtime dependencies.


โšก Performance

  • โ—†โšก < 1ms typical parse time (cached: ~0.01ms)
  • โ—†๐Ÿชถ Zero dependencies
  • โ—†๐Ÿ” Built-in LRU+TTL cache (2000 entries / 10-minute TTL by default)
  • โ—†๐ŸŒณ Fully tree-shakable via subpath exports
  • โ—†๐Ÿ“ฆ ~40 KB full bundle, much less when tree-shaken

Disable the cache for individual calls when needed:

ts
phonex("+254712345678", { noCache: true });
phonex.clearCache();   // wipe the entire cache

๐ŸŒ Country Coverage

Phonex includes:

  • โ—†Full ITU-T E.164 calling code table (200+ countries) โ€” every country can be detected from its calling code.
  • โ—†Curated strict-validation metadata for 30+ high-traffic countries: KE, US, GB, DE, FR, NG, ZA, IN, BR, CA, AU, JP, CN, MX, ES, IT, NL, RU, SA, AE, EG, GH, UG, TZ, RW, ET, SG, ID, PH, KR, TR.
  • โ—†For countries outside the curated set, strict mode falls back to length-only validation and flags metadataAvailable: false in the response โ€” so you always know the confidence level.

This is intentional: rather than ship 250 hand-rolled regexes that may be inaccurate, we ship a smaller curated set we've verified, plus a clear honest API for the long tail.


๐Ÿง  Use Cases

  • โ—†Signup & authentication โ€” validate at the form, normalize for storage
  • โ—†Fintech & KYC โ€” strict-mode validation before money moves
  • โ—†CRM data cleaning โ€” analytics over messy historical records
  • โ—†Messaging platforms โ€” pick the right channel (SMS / WhatsApp / voice)
  • โ—†AI agents & LLM tools โ€” structured phone intelligence with confidence scores
  • โ—†Fraud detection โ€” flag fake numbers before you spend money on lookup APIs

๐Ÿ“˜ TypeScript

Full type definitions ship with the package. All public APIs are strictly typed:

ts
import type {
  PhonexResult,
  PhonexOptions,
  ValidationLevel,
  RiskAssessment,
  PhoneType,
  AnalyticsResult,
} from "@munesoft/phonex";

๐Ÿ†š Comparison

| Feature | @munesoft/phonex | libphonenumber-js | |---|---|---| | Parsing | โœ… | โœ… | | Formatting | โœ… | โœ… | | Strict validation | โœ… | โœ… | | AI / anomaly mode | โœ… | โŒ | | Risk / spam detection | โœ… | โŒ | | Carrier detection | โœ… (curated) | โŒ | | Channel detection (SMS/WhatsApp/voice) | โœ… | โŒ | | Built-in LRU cache | โœ… | โŒ | | Bulk + streaming | โœ… | โŒ | | Suggestions for malformed input | โœ… | โŒ | | Privacy mode (mask / hash) | โœ… | โŒ | | Express middleware | โœ… | โŒ | | Plugin system | โœ… | โŒ | | Country coverage (parsing) | 200+ | 240+ | | Country coverage (strict validation) | 30 (curated) | 240 (autogenerated) | | Bundle size (minified) | ~40 KB | ~145 KB | | Zero dependencies | โœ… | โœ… |

Phonex is not a replacement for libphonenumber-js if you need exhaustive coverage of every country's regulatory metadata. It's the AI-first intelligence layer built for modern apps that care about developer ergonomics, AI compatibility, and feature density over raw country-count metrics.


๐Ÿ›ฃ Roadmap

  • โ—†[ ] Real-time CDN-backed metadata updates
  • โ—†[ ] ML-powered fraud detection plugin
  • โ—†[ ] Expanded carrier database
  • โ—†[ ] Plugin ecosystem (Twilio Lookup, Numverify, Truecaller adapters)
  • โ—†[ ] React hook (usePhonex)
  • โ—†[ ] CLI (npx phonex check +254...)

๐Ÿ” Keywords

phone number validation javascript ยท format phone number nodejs ยท international phone parser ยท libphonenumber alternative ยท validate phone number api ยท phone number ai validation ยท detect country from phone number ยท spam phone number detection ยท phone number carrier lookup ยท e164 formatter ยท whatsapp number validator ยท OTP delivery validation ยท KYC phone validation ยท CRM phone normalization


๐Ÿ“„ License

MIT ยฉ munesoft


๐Ÿ’ก Final Positioning

Phonex is not just a phone number library. It's the communication intelligence layer for modern apps and AI systems.

<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=5184679f-42b6-4929-a50e-a11172871f96" />