sri-lanka-nic@sri-lanka/nic

Validation

The library provides three ways to validate NIC numbers, each suited for different use cases.

NIC.valid()

Returns true or false without throwing. Perfect for form validation:

NIC.valid("901404567V"); // true
NIC.valid("invalid"); // false

Tip: NIC.valid() only catches NICError. If your custom check function throws a different error type (like TypeError), it will still propagate.

NIC.safeParse()

Returns a result object with either the parsed data or the error. Never throws:

const result = NIC.safeParse("901404567V");
 
if (result.success) {
  console.log(result.data.gender); // "MALE"
} else {
  console.log(result.error.message); // error details
}

Unlike valid(), which only tells you true/false, safeParse gives you the parsed data on success and the actual error on failure — all without needing try/catch.

NIC.parse()

Parsing also validates. If the NIC is invalid, .parse() throws before returning any data:

try {
  const result = NIC.parse("invalid");
} catch (error) {
  // NICError: "Invalid NIC structure"
}

NIC.validate()

Deprecated: Having both .valid() and .validate() causes developer confusion. validate acts purely as an assertion, which can be achieved directly through NIC.parse(). Therefore, this method is deprecated to simplify the API and will be removed in a future major release. Use NIC.parse() instead.

Throws a NICError if the NIC is invalid. Use this when you want to halt execution on bad input:

import { NIC } from "@sri-lanka/nic";
 
NIC.validate("901404567V"); // passes silently
NIC.validate("invalid"); // throws NICError: "Invalid NIC structure"

Validation Pipeline Order

When you parse or validate a NIC, the library executes checks in a very specific order:

  1. Sanitization: Trims whitespace and converts trailing letters to uppercase.
  2. Structural Validation: Tests the string against strict Regular Expressions to ensure it is exactly 12 digits or 9 digits plus V/X.
  3. Extraction: Calculates the year and days from the raw string.
  4. Type Restrictions: If onlyNew or onlyOld is set, rejects NICs of the wrong format.
  5. Logic Validations: Verifies that the days field is a valid day number (1–366), and that the computed age falls within the permitted minimum/maximum limits.
  6. Custom Validation (check callback): Finally, if you provided a check function in the config, it executes your custom rules. This guarantees your custom function only runs if the NIC is structurally and mathematically sound.

What Gets Validated

The library checks these things automatically:

  1. Structure — Must match either 12-digit or 9-digit+letter pattern
  2. Day of year — Must be between 1 and 366. The NIC system always treats every year as having 366 days (February always has 29 days), so 366 is valid for any birth year, not just leap years. See How Birthday Dates Are Encoded for the full explanation.
  3. Birth year — Must be within the allowed birth year range (default: 1900 to current year minus minimum age). Old format NICs are additionally restricted to years 1900–1999.
  4. Minimum age — Default: 15 (legal age to hold a NIC)
  5. Maximum age — Default: current year minus 1900
  6. Type restrictions — If onlyNew or onlyOld is set, the NIC must be the specified format

What is NOT Validated

Because this library runs purely offline mathematical checks, it does not:

  • Check against government databases — It cannot verify if a NIC has actually been issued to a real person.
  • Verify the serial number or letter — The serial number indicates the sequence of issue, and the trailing letter (V/X) indicates voter status. These cannot be validated offline.
  • Verify the check digit — The exact modulo algorithm used by the Department for Registration of Persons to calculate the final digit is not public. The library ensures it is a number, but cannot verify if it is mathematically correct.

Error Handling

All validation errors are instances of NICError:

import { NIC, NICError } from "@sri-lanka/nic";
 
try {
  NIC.parse("invalid");
} catch (error) {
  if (error instanceof NICError) {
    console.log(error.message); // "Invalid NIC structure"
    console.log(error.name); // "NICError"
  }
}

See the Errors page for a full list of error messages.