Getting Started
Welcome to @indodev/toolkit! This guide will help you get up and running in minutes.
What is @indodev/toolkit?
@indodev/toolkit is a TypeScript library that provides utilities for Indonesian-specific data validation and formatting. It’s designed to solve common challenges when building applications that handle Indonesian data like national IDs (NIK), phone numbers, and currency.
Why Use This Library?
- 🎯 Indonesian-First - Built specifically for Indonesian data formats and standards
- 📦 Zero Dependencies - Lightweight with no external dependencies (~30KB)
- 🔒 Type-Safe - Full TypeScript support with complete type definitions
- 🧪 Battle-Tested - 95%+ test coverage with 470+ test cases
- 🌳 Tree-Shakeable - Import only what you need for optimal bundle size
- ⚡ Framework-Agnostic - Works with React, Vue, Svelte, or vanilla JavaScript
Key Features
- NIK Module: Validate, parse, format, and mask Indonesian National Identity Numbers
- Phone Module: Validate, format, and detect operators for Indonesian phone numbers
- Currency Module: Format Rupiah, convert to words (terbilang), and parse amounts
Installation
npm
npm install @indodev/toolkitRequirements: Node.js 16+ or any modern browser. Works with TypeScript 4.5+ or JavaScript.
Quick Start
Import Syntax
The library uses subpath imports for optimal tree-shaking. Import only the modules you need:
// ✅ Recommended: Import from specific modules
import { validateNIK, parseNIK } from '@indodev/toolkit/nik'
import { formatPhoneNumber } from '@indodev/toolkit/phone'
import { formatRupiah } from '@indodev/toolkit/currency'
// ❌ Avoid: Importing from root (imports everything)
import { validateNIK } from '@indodev/toolkit'NIK (National Identity Number)
Validate and extract information from Indonesian NIK:
import { validateNIK, parseNIK, formatNIK, maskNIK } from '@indodev/toolkit/nik'
// Validate NIK format
const isValid = validateNIK('3201234567890123')
console.log(isValid) // true
// Parse and extract information
const info = parseNIK('3201018901310123')
console.log(info)
// {
// province: { code: '32', name: 'Jawa Barat' },
// regency: { code: '01', name: 'Kab. Bogor' },
// district: { code: '01', name: null },
// birthDate: Date(1989-01-31),
// gender: 'male',
// serialNumber: '0123',
// isValid: true
// }
// Format with separators
const formatted = formatNIK('3201234567890123')
console.log(formatted) // '32-01-23-45-67-89-0123'
// Mask for privacy
const masked = maskNIK('3201234567890123')
console.log(masked) // '3201********0123'Learn more: NIK Module Documentation →
Phone Numbers
Validate, format, and detect operators for Indonesian phone numbers:
import {
validatePhoneNumber,
formatPhoneNumber,
parsePhoneNumber,
getOperator
} from '@indodev/toolkit/phone'
// Validate phone number
const isValid = validatePhoneNumber('081234567890')
console.log(isValid) // true
// Format to different styles
const international = formatPhoneNumber('081234567890', 'international')
console.log(international) // '+62 812-3456-7890'
const national = formatPhoneNumber('081234567890', 'national')
console.log(national) // '0812-3456-7890'
const e164 = formatPhoneNumber('081234567890', 'e164')
console.log(e164) // '6281234567890'
// Detect operator
const operator = getOperator('081234567890')
console.log(operator) // 'Telkomsel'
// Parse all information
const info = parsePhoneNumber('081234567890')
console.log(info)
// {
// countryCode: '62',
// operator: 'Telkomsel',
// number: '81234567890',
// formatted: {
// international: '+62 812-3456-7890',
// national: '0812-3456-7890',
// e164: '6281234567890'
// },
// isMobile: true,
// isLandline: false
// }Learn more: Phone Module Documentation →
Currency (Rupiah)
Format Indonesian Rupiah and convert numbers to words (terbilang):
import {
formatRupiah,
formatCompact,
parseRupiah,
toWords
} from '@indodev/toolkit/currency'
// Format as Rupiah
const formatted = formatRupiah(1500000)
console.log(formatted) // 'Rp 1.500.000'
// With decimals
const withDecimals = formatRupiah(1500000.50, { decimal: true })
console.log(withDecimals) // 'Rp 1.500.000,50'
// Compact format (Indonesian style)
const compact = formatCompact(1500000)
console.log(compact) // 'Rp 1,5 juta'
// Parse formatted string back to number
const amount = parseRupiah('Rp 1.500.000')
console.log(amount) // 1500000
// Convert to Indonesian words (terbilang)
const words = toWords(1500000)
console.log(words) // 'satu juta lima ratus ribu rupiah'
// With options
const capitalizedWords = toWords(1500000, { uppercase: true })
console.log(capitalizedWords) // 'Satu juta lima ratus ribu rupiah'Learn more: Currency Module Documentation →
TypeScript Configuration
For the best TypeScript experience, ensure your tsconfig.json includes:
{
"compilerOptions": {
"moduleResolution": "bundler", // or "node16" / "nodenext"
"resolvePackageJsonExports": true,
"resolvePackageJsonImports": true
}
}This enables proper resolution of subpath imports (@indodev/toolkit/nik, etc.).
Framework Integration
React / Next.js
import { validateNIK, parseNIK } from '@indodev/toolkit/nik'
import { useState } from 'react'
function NIKValidator() {
const [nik, setNIK] = useState('')
const info = nik ? parseNIK(nik) : null
return (
<div>
<input
value={nik}
onChange={e => setNIK(e.target.value)}
placeholder="Enter NIK"
className={info ? 'valid' : 'invalid'}
/>
{info && (
<div>
<p>Province: {info.province.name}</p>
<p>Gender: {info.gender}</p>
<p>Birth Date: {info.birthDate?.toLocaleDateString('id-ID')}</p>
</div>
)}
</div>
)
}Vue
<script setup>
import { ref, computed } from 'vue'
import { validatePhoneNumber, formatPhoneNumber } from '@indodev/toolkit/phone'
const phone = ref('')
const isValid = computed(() => validatePhoneNumber(phone.value))
const formatted = computed(() =>
isValid.value ? formatPhoneNumber(phone.value, 'national') : ''
)
</script>
<template>
<div>
<input v-model="phone" placeholder="Phone number" />
<p v-if="formatted">Formatted: {{ formatted }}</p>
</div>
</template>Svelte
<script>
import { formatRupiah, parseRupiah } from '@indodev/toolkit/currency'
let amount = ''
$: formatted = parseRupiah(amount)
? formatRupiah(parseRupiah(amount))
: ''
</script>
<input bind:value={amount} placeholder="Amount" />
{#if formatted}
<p>Formatted: {formatted}</p>
{/if}Bundle Size
The library is optimized for minimal bundle impact:
| Module | Size (minified + gzipped) |
|---|---|
| NIK | ~8KB |
| Phone | ~12KB |
| Currency | ~10KB |
| Full library | ~30KB |
Thanks to tree-shaking, you only pay for what you use!
Browser Compatibility
Works in all modern browsers and Node.js:
- ✅ Chrome/Edge 90+
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Node.js 16+
- ✅ Deno
- ✅ Bun
No polyfills needed for modern environments. For older browsers, ensure your bundler includes necessary polyfills.
Next Steps
Explore the Modules
Dive deep into each module’s capabilities:
- NIK - National ID validation and parsing
- Phone - Phone number utilities
- Currency - Rupiah formatting and terbilang
Check Examples (Coming Soon)
See real-world implementations:
- Form validation patterns
- Invoice generation
- Data processing workflows