A JavaScript/TypeScript library for validating and parsing Serbian unique master citizen numbers (JMBG - Jedinstveni Matični Broj Građana).
- ✅ Validate JMBG numbers with comprehensive checks
- ✅ Extract birth date, region, and gender information
- ✅ Support for all Serbian regions
- ✅ Calculate age from JMBG
- ✅ Full TypeScript support with type definitions
- ✅ Fully tested with Vitest
- ✅ Zero dependencies
- ✅ CommonJS and ESM support
Install via npm:
npm install @jmbg-labs/jmbgOr with yarn:
yarn add @jmbg-labs/jmbgOr with pnpm:
pnpm add @jmbg-labs/jmbgimport { Jmbg } from '@jmbg-labs/jmbg';
// Quick validation
if (Jmbg.valid('0101000710009')) {
console.log('Valid JMBG');
}
// Parse and validate
try {
const jmbg = Jmbg.parse('0101000710009');
console.log('Valid JMBG:', jmbg.format());
} catch (error) {
console.error('Invalid JMBG:', error.message);
}import { Jmbg } from '@jmbg-labs/jmbg';
const jmbg = new Jmbg('0101000710009');
// Get birth date
const date = jmbg.getDate(); // Date object
console.log(date.toISOString()); // 2000-01-01T00:00:00.000Z
// Get age
console.log(jmbg.getAge()); // e.g., 26
// Check gender
if (jmbg.isMale()) {
console.log('Male');
}
if (jmbg.isFemale()) {
console.log('Female');
}
// Access individual parts
console.log(jmbg.get('day')); // 1
console.log(jmbg.get('month')); // 1
console.log(jmbg.get('year')); // 2000
console.log(jmbg.get('region')); // 71
console.log(jmbg.get('regionText')); // "Belgrade"
console.log(jmbg.get('country')); // "Serbia"
console.log(jmbg.get('unique')); // 0
console.log(jmbg.get('checksum')); // 9const jmbg = new Jmbg('1505995800002');
// String conversion
console.log(jmbg.toString()); // "1505995800002"
console.log(jmbg.format()); // "1505995800002"
// Access original parts
console.log(jmbg.get('original')); // "1505995800002"
console.log(jmbg.get('dayOriginal')); // "15"
console.log(jmbg.get('monthOriginal')); // "05"
console.log(jmbg.get('yearOriginal')); // "995"
console.log(jmbg.get('regionOriginal')); // "80"
console.log(jmbg.get('uniqueOriginal')); // "000"
// Check property existence
if (jmbg.has('regionText')) {
console.log(jmbg.get('regionText')); // "Novi Sad"
}JMBG consists of 13 digits: DDMMYYYRRBBBC
- DD - Day of birth (01-31)
- MM - Month of birth (01-12)
- YYY - Year of birth (last 3 digits)
- RR - Region code
- BBB - Unique number (000-499 for males, 500-999 for females)
- C - Checksum digit
The library supports all Serbian and ex-Yugoslav regions including (beware: ex-Yugoslav regions codes may have changed since the breakup):
- Serbia (71-79): Belgrade, Kragujevac, Niš, etc.
- Serbia/Vojvodina (80-89): Novi Sad, Subotica, Pančevo, etc.
- Serbia/Kosovo (91-96): Priština, Peć, Prizren, etc.
- Bosnia and Herzegovina (10-19)
- Montenegro (21-29)
- Croatia (30-39)
- Macedonia (41-49)
- Slovenia (50)
The library performs comprehensive validation:
- Length check - Must be exactly 13 digits
- Format check - Must contain only numeric characters
- Date validation - Birth date must be valid (including leap year support)
- Region validation - Region code must exist in the registry
- Checksum validation - Modulo 11 algorithm verification
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage# Build the library
npm run build
# Build in watch mode
npm run dev# Lint code
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Check formatting
npm run format:check- Node.js >=16.0.0
- No external dependencies (for production use)
This library is written in TypeScript and includes full type definitions. No additional @types package is needed.
import { Jmbg, JmbgError, JmbgParts } from '@jmbg-labs/jmbg';
// Full type safety
const jmbg: Jmbg = new Jmbg('0101000710009');
const parts: JmbgParts | null = jmbg.get('day');Contributions are welcome! Please ensure:
- All tests pass (
npm test) - Code follows the style guide (
npm run lint) - Add tests for new features
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
Developed by JMBG Labs
const jmbgs = ['0710003730015', '1705978730032', 'invalid'];
for (const jmbgString of jmbgs) {
if (Jmbg.valid(jmbgString)) {
const jmbg = Jmbg.parse(jmbgString);
console.log(
`${jmbg.format()} - Born: ${jmbg.getDate().toISOString().split('T')[0]}, ` +
`Region: ${jmbg.get('regionText')}, ` +
`Gender: ${jmbg.isMale() ? 'Male' : 'Female'}`
);
} else {
console.log(`${jmbgString} - Invalid`);
}
}const jmbg = new Jmbg('0710003730015');
const age = jmbg.getAge();
if (age >= 18) {
console.log('Adult');
} else {
console.log('Minor');
}import { Jmbg, JmbgError } from '@jmbg-labs/jmbg';
try {
const jmbg = new Jmbg('1234567890123');
} catch (error) {
if (error instanceof JmbgError) {
// Handle specific validation errors
console.error('Validation failed:', error.message);
// Possible messages:
// - "Input string must have 13 digits."
// - "JMBG string must have 13 digits."
// - "Date '...' is not valid."
// - "Region '...' is not valid for Serbian JMBG."
// - "Checksum is not valid."
}
}const { Jmbg } = require('@jmbg-labs/jmbg');
const jmbg = new Jmbg('0101000710009');
console.log(jmbg.getAge());import { Jmbg } from '@jmbg-labs/jmbg';
const jmbg = new Jmbg('0101000710009');
console.log(jmbg.getAge());