NIK-lookup
High-performance, lightweight Indonesian National Identity Number (Nomor Induk Kependudukan — NIK) parser and validator for JavaScript/TypeScript and Python, powered by the official kodenik database.
Features
- $O(1)$ Hash Map Lookups: Sub-microsecond regional resolution using pre-indexed 6-digit prefix lookups from
kodenik. - Zero External Runtime Dependencies: Built entirely with native language runtimes and standard libraries (beyond
kodenik). - Comprehensive Calendar Validation: Strict validation including 30-day month limits, February leap-year logic ($YY \pmod 4 = 0$, $2000$ leap), and century resolution.
- Dual-Ecosystem Distribution: Available as both an npm package (
nik-lookup) and a pip package (nik-lookup). - TypeScript & PEP 561 Typing: Hand-authored
.d.tstypes for TypeScript andpy.typedmarker formypy/pyright. - Immutable & Safe: Frozen parsed instances prevent accidental mutations; provides
tryParse/try_parseandisValid/is_validfor non-throwing validation flows. - 100% Backward Compatible: Preserves all legacy Indonesian attribute names (
provinsi,kabkota,kecamatan,tanggal_lahir, etc.).
16-Digit NIK Structure
[ P P ][ K K ][ C C ][ D D ][ M M ][ Y Y ][ S S S S ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|-- Wilayah (6) -----|----- Tanggal Lahir -----|-- Urut --|
- Digits 1–2 (
PP): Provincial code (kode_provinsi, 38 official provinces). - Digits 3–4 (
KK): Regency/City code (kode_kabkota,01–69Kabupaten,71–99Kota). - Digits 5–6 (
CC): District code (kode_kecamatan,01–55). - Digits 7–8 (
DD): Day of birth (Male:01–31; Female:41–71, where $\text{Actual Day} = \text{DD} - 40$). - Digits 9–10 (
MM): Month of birth (01–12). - Digits 11–12 (
YY): 2-digit birth year (century resolved against sliding window). - Digits 13–16 (
SSSS): 4-digit unique civil registration sequential number (0001–9999).
JavaScript / TypeScript Usage
Installation
npm install nik-lookup kodenik
ECMAScript Modules (ESM)
import { NIK, parse, tryParse, isValid } from 'nik-lookup';
// Standard parsing
const nik = new NIK('3174071708450001');
console.log(nik.provinsi); // "DKI Jakarta"
console.log(nik.kabkota); // "Kota Jakarta Selatan"
console.log(nik.kecamatan); // "Kebayoran Baru"
console.log(nik.tanggal_lahir); // 17
console.log(nik.bulan_lahir); // 8
console.log(nik.tahun_lahir); // 45
console.log(nik.jenis_kelamin); // "Laki - laki"
console.log(nik.kode_unik); // "0001"
// Modern English attributes
console.log(nik.province); // "DKI Jakarta"
console.log(nik.regency); // "Kota Jakarta Selatan"
console.log(nik.district); // "Kebayoran Baru"
console.log(nik.gender); // "male"
console.log(nik.birthYear); // 1945
console.log(nik.birthDateString); // "1945-08-17"
CommonJS (CJS)
const { NIK, tryParse, isValid } = require('nik-lookup');
const nik = new NIK('3273016104790002');
console.log(nik.provinsi); // "Jawa Barat"
console.log(nik.tanggal_lahir); // 21 (Female 61 - 40 = 21)
console.log(nik.jenis_kelamin); // "Perempuan"
Non-Throwing Validation
import { tryParse, isValid } from 'nik-lookup';
if (isValid('3174071708450001')) {
console.log('Valid NIK');
}
const result = tryParse('invalid-nik');
// result === null
Python Usage
Installation
pip install nik-lookup kodenik
Python Quickstart
from nik_lookup import NIK, parse, try_parse, is_valid
# Standard parsing
nik = NIK("3174071708450001")
# Indonesian attributes (legacy compatibility)
print(nik.provinsi) # "DKI Jakarta"
print(nik.kabkota) # "Kota Jakarta Selatan"
print(nik.kecamatan) # "Kebayoran Baru"
print(nik.tanggal_lahir) # 17
print(nik.bulan_lahir) # 8
print(nik.tahun_lahir) # 45
print(nik.jenis_kelamin) # "Laki - laki"
print(nik.kode_unik) # "0001"
# Modern attributes
print(nik.province) # "DKI Jakarta"
print(nik.regency) # "Kota Jakarta Selatan"
print(nik.district) # "Kebayoran Baru"
print(nik.province_code) # "31"
print(nik.regency_code) # "74"
print(nik.district_code) # "07"
print(nik.gender) # "male"
print(nik.birth_year) # 1945
print(nik.birth_date) # datetime.date(1945, 8, 17)
print(nik.birth_date_string)# "1945-08-17"
print(nik.serial_number) # "0001"
Safe Parsing & Dictionary Export
from nik_lookup import try_parse, is_valid
# Safe validation without exceptions
if is_valid("3174071708450001"):
print("NIK is valid")
parsed = try_parse("invalid")
# parsed is None
# Export to dictionary
data = nik.to_dict()
print(data["birth_date"]) # "1945-08-17"
Error Handling
Both implementations provide typed exceptions inheriting from standard error bases:
| Exception (JS / TS) | Exception (Python) | Trigger Condition |
|---|---|---|
NikTypeError |
NikTypeError |
Input is not a string (TypeError) |
InvalidNikLengthError |
InvalidNikLengthError |
Input length is not exactly 16 characters |
InvalidNikFormatError |
InvalidNikFormatError |
Input contains non-numeric characters |
InvalidNikDateError |
InvalidNikDateError |
Invalid calendar date, invalid month, or non-leap year Feb 29 |
UnknownAdministrativeCodeError |
UnknownAdministrativeCodeError |
Province, regency, or district code not in database |
All custom exceptions inherit from NikError (Error in JS, ValueError in Python).
Testing
Both packages include zero-dependency test suites:
# Run Node.js test suite (node:test)
npm test
# Run Python test suite (unittest)
python3 -m unittest discover -s test -p "test_*.py"
License
MIT © Faiz A
Metadata
Release files for nik-lookup 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nik_lookup-1.0.0.tar.gz | 9.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nik_lookup-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.5 kB
Release files / nik_lookup-1.0.0.tar.gz
| Download URL | nik_lookup-1.0.0.tar.gz |
|---|---|
| Size | 9.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
673cab592e111d9167d46b7e6a0a2698cd5d3859f63052dcd4e8ab272d568f52
|
|
BLAKE2b-256 checksum How to use checksums |
3f65c618304f5e7ee7c87a06697f54165f779fa2b8a836470243346fe045ef4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / nik_lookup-1.0.0-py3-none-any.whl
| Download URL | nik_lookup-1.0.0-py3-none-any.whl |
|---|---|
| Size | 8.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8acd302e479ef81c1d44e923baf4be411121dc2b642e056f57cb75eaec6e1a2
|
|
BLAKE2b-256 checksum How to use checksums |
df43db520ae4660afe70c8c3930493e4300146ca1b5fd6875af0e432a728ae84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|