@indodev/toolkit
Build for Indonesian data. Zero dependencies. Type-safe.
Stop wrestling with NIK validation, Rupiah formatting, and phone normalization. This library handles Indonesian-specific rules so you can focus on building your product.
Stats
| Metric | Value |
|---|---|
| Test cases | 1512+ |
| Coverage | 95%+ |
| Dependencies | Zero |
| Bundle size | <50KB (total) |
| Modules | 9 |
Modules
| Module | Description |
|---|---|
| NIK | Validate and parse Indonesian National Identity Numbers |
| NPWP | Validate and format Tax Identification Numbers |
| Phone | Format, validate, and parse phone numbers |
| Validate email addresses with domain detection | |
| Vehicle Plate | Validate Indonesian license plates |
| VIN | Validate and decode Vehicle Identification Numbers |
| Currency | Format Rupiah, terbilang, split amounts |
| Text | Title case, slug, abbreviation, case conversion |
| DateTime | Indonesian date formatting, relative time, age calculation, timezones |
Before / After
See the difference between manual validation and using this library.
Before: Manual validation with edge cases
// Does this NIK even make sense?
const isValid = nik.length === 16 && parseInt(nik.slice(0, 2)) > 0;
// What province is code 32? What about gender?
// You'd need to look up a reference table...After: One line, full context
import { parseNIK } from '@indodev/toolkit/nik';
const info = parseNIK('3201234567890123');
// {
// province: { code: '32', name: 'Jawa Barat' },
// gender: 'Male',
// birthDate: 1990-01-01,
// uniqueCode: 1234
// }Before: Rupiah formatting with toLocaleString
// Browser-dependent, inconsistent across environments
const formatted = new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
}).format(1500000);
// 'Rp1.500.000,00' (no space, always shows decimals)After: Consistent, Indonesian grammar
import { formatRupiah, formatCompact } from '@indodev/toolkit/currency';
formatRupiah(1500000); // 'Rp 1.500.000'
formatCompact(1500000); // 'Rp 1,5 juta' (not '1,0 juta')
toWords(1500000); // 'satu juta lima ratus ribu rupiah'Why This Library
- Indonesian-specific rules baked in — NIK gender detection, Rupiah grammar (“1,5 juta” not “1,0 juta”), Indonesian conjunctions in slugs (”&” becomes “dan”), area code detection. All handled automatically.
- Zero dependencies, tree-shakeable — Import only what you need. Each module is independent. No moment.js, no lodash, no bloat.
- Pure functions, predictable output — Same input, same output. No side effects, no global state, no surprises.
- Full TypeScript support — Every function is typed. Every return value is typed. Every error case is documented.
Installation
npm
npm install @indodev/toolkitQuick Start
import { validateNIK, parseNIK } from '@indodev/toolkit/nik';
import { formatPhoneNumber } from '@indodev/toolkit/phone';
import { formatRupiah, formatCompact } from '@indodev/toolkit/currency';
import { slugify } from '@indodev/toolkit/text';
// NIK validation and parsing
validateNIK('3201234567890123'); // true
parseNIK('3201234567890123').province.name; // 'Jawa Barat'
// Phone formatting
formatPhoneNumber('081234567890', 'international'); // '+62 812-3456-7890'
// Currency with proper grammar
formatCompact(1500000); // 'Rp 1,5 juta'
formatCompact(1000000); // 'Rp 1 juta' (not '1,0 juta')
// Indonesian-aware slug
slugify('Pria & Wanita'); // 'pria-dan-wanita'
// Date formatting in Indonesian
import { formatDate, parseDate } from '@indodev/toolkit/datetime';
formatDate(new Date('2026-01-02'), 'long'); // '2 Januari 2026'
parseDate('02-01-2026'); // Date(2026, 0, 2)
## What's Next
- **[Get Started](/docs/get-started)** - Installation, TypeScript configuration, and framework integration guides
- **[Browse API](/docs/identity/nik)** - Complete API reference for all 9 modules with examples and edge cases
- **[View on GitHub](https://github.com/choiruladamm/indo-dev-utils)** - Source code, issues, and contribution guidelinesLast updated on