Validate and parse Polish identification numbers — PESEL, NIP, REGON, KRS, NRB, VAT-EU, IBAN, ID Card, and Passport. Rich value objects, detailed error reasons, zero production dependencies. TypeScript-first.
JavaScript/TypeScript port of slashlab/numerik (PHP).
npm install @slashlab/numerik-js
# or
pnpm add @slashlab/numerik-jsimport { Numerik } from '@slashlab/numerik-js'
// Simple boolean check
Numerik.pesel().isValid('92060512186') // true
Numerik.nip().isValid('5260250274') // true
// Rich validation result with failure reasons
const result = Numerik.pesel().validate('92060512185') // wrong checksum
result.isFailed() // true
result.getFirstFailure().reason // ValidationFailureReason.InvalidChecksum
// Parse to value object
const pesel = Numerik.pesel().parse('92060512186')
pesel.getBirthDate() // Date object: 1992-06-05
pesel.getGender() // Gender.Female
pesel.isAdult() // true
// Try-parse (returns null on failure instead of throwing)
const parsed = Numerik.nip().tryParse('5260250274')
parsed?.getFormatted() // '526-025-02-74'All identifiers accept an optional strict flag (default: true). In non-strict mode formatting variations (spaces, dashes) are accepted:
Numerik.nip(false).isValid('526 025 02 74') // true
Numerik.nip(true).isValid('526 025 02 74') // falseimport { peselSchema, nipParseSchema } from '@slashlab/numerik-js/zod'
import { z } from 'zod'
const schema = z.object({
pesel: peselSchema(), // validates, keeps string
nip: nipParseSchema(), // validates and transforms to Nip value object
})| Group | Identifier | Class |
|---|---|---|
| Personal | PESEL | PeselIdentifier |
| Personal | ID Card | IdCardIdentifier |
| Personal | Passport | PassportIdentifier |
| Tax | NIP | NipIdentifier |
| Tax | VAT-EU | VatEuIdentifier |
| Business | REGON | RegonIdentifier |
| Business | KRS | KrsIdentifier |
| Banking | NRB | NrbIdentifier |
| Banking | IBAN | IbanIdentifier |
See CHANGELOG.md.
See CONTRIBUTING.md.
See SECURITY.md.
MIT — see LICENSE.
If this saved you time → ☕ Buy me a coffee