nepali
v2.0.0
Published
Lightweight, tree-shakeable utilities for Nepali provinces, cities, and BS date conversion.
Maintainers
Readme
nepali
Lightweight, tree-shakeable utilities for the Nepali ecosystem — Bikram Sambat (BS) date conversion, provinces, districts, and cities of Nepal.
No runtime dependencies. ~5 KB. Full TypeScript support. Works with React, Next.js, Vue, and plain Node.js.
Table of Contents
- What is this?
- Installation
- Quick Start
- Usage with React
- Usage with Next.js
- Usage with plain Node.js
- API Reference
- TypeScript
- Migration from v1
- Supported Range
- License
What is this?
Nepal uses the Bikram Sambat (BS) calendar — approximately 56–57 years ahead of the Gregorian (AD) calendar. Most Nepali government documents, banks, schools, and official records use BS dates. The Nepali New Year starts in mid-April.
This package gives you:
- AD → BS date conversion with formatting and validation
- Province, district, and city data for all 7 provinces of Nepal
- Bilingual output — every function returns either Nepali (Devanagari) or English
- Zero runtime dependencies — nothing gets installed in your users' browsers
// April 13, 2024 (AD) is Baisakh 1, 2081 (BS) — Nepali New Year
adToBs(2024, 4, 13)
// → { year: 2081, month: 1, day: 1 }Installation
npm install nepaliyarn add nepalipnpm add nepaliQuick Start
import { adToBs, todayFormatted, isValidBsDate } from 'nepali/date';
import { getProvinceByDistrict, getDistrictNames } from 'nepali/province';
// Convert AD date to BS
adToBs(2024, 4, 13)
// → { year: 2081, month: 1, day: 1 }
// Today's date formatted in Nepali
todayFormatted()
// → '२०८२ बैशाख १४'
todayFormatted('MMM DD, YYYY')
// → 'Baisakh 14, २०८२'
// Validate a BS date (great for forms)
isValidBsDate(2081, 1, 31) // true
isValidBsDate(2081, 1, 32) // false
// Find which province a district is in
getProvinceByDistrict('Kaski', { lang: 'en' })
// → { name: 'Gandaki Pradesh', capital: 'Pokhara' }
// All 77 district names
getDistrictNames({ lang: 'en' })
// → ['Taplejung', 'Panchthar', 'Ilam', ...]Usage with React
Display today's Nepali date
import { todayFormatted, todayBs, getMonthNames } from 'nepali/date';
export default function NepaliDateDisplay() {
const { year, month, day } = todayBs();
const monthNames = getMonthNames('en');
return (
<div>
<h2>आजको मिति</h2>
<p className="nepali-date">{todayFormatted()}</p>
<p className="english-date">
{monthNames[month - 1]} {day}, {year} BS
</p>
</div>
);
}BS date picker with validation
import { useState } from 'react';
import { isValidBsDate, getDaysInBsMonth, getMonthNames } from 'nepali/date';
export default function BsDatePicker() {
const [year, setYear] = useState(2081);
const [month, setMonth] = useState(1);
const [day, setDay] = useState(1);
const monthNames = getMonthNames('en');
const daysInMonth = isValidBsDate(year, month, 1)
? getDaysInBsMonth(year, month)
: 30;
const isValid = isValidBsDate(year, month, day);
return (
<div>
<select value={month} onChange={e => setMonth(Number(e.target.value))}>
{monthNames.map((name, i) => (
<option key={i} value={i + 1}>{name}</option>
))}
</select>
<select value={day} onChange={e => setDay(Number(e.target.value))}>
{Array.from({ length: daysInMonth }, (_, i) => i + 1).map(d => (
<option key={d} value={d}>{d}</option>
))}
</select>
<input
type="number"
value={year}
onChange={e => setYear(Number(e.target.value))}
min={2000}
max={2099}
/>
{!isValid && <p style={{ color: 'red' }}>Invalid BS date</p>}
</div>
);
}Province and district selector
import { useState } from 'react';
import { getAllProvinces, getDistricts } from 'nepali/province';
export default function LocationSelector() {
const [selectedProvince, setSelectedProvince] = useState('');
const [selectedDistrict, setSelectedDistrict] = useState('');
const provinces = getAllProvinces({ lang: 'en' });
const districts = selectedProvince
? getDistricts(selectedProvince, { lang: 'en' })
: [];
return (
<div>
<select
value={selectedProvince}
onChange={e => {
setSelectedProvince(e.target.value);
setSelectedDistrict('');
}}
>
<option value="">Select Province</option>
{provinces.map(p => (
<option key={p.name} value={p.name}>{p.name}</option>
))}
</select>
<select
value={selectedDistrict}
onChange={e => setSelectedDistrict(e.target.value)}
disabled={!selectedProvince}
>
<option value="">Select District</option>
{districts.map(d => (
<option key={d} value={d}>{d}</option>
))}
</select>
</div>
);
}Convert a user-entered AD date to BS
import { useState } from 'react';
import { adToBs, formatBsDate } from 'nepali/date';
export default function DateConverter() {
const [adDate, setAdDate] = useState('');
const [bsDate, setBsDate] = useState(null);
const [error, setError] = useState('');
function convert() {
setError('');
setBsDate(null);
const [year, month, day] = adDate.split('-').map(Number);
try {
const result = adToBs(year, month, day);
setBsDate(formatBsDate(result, 'YYYY MMMM DD'));
} catch (e) {
setError(e.message);
}
}
return (
<div>
<input
type="date"
value={adDate}
onChange={e => setAdDate(e.target.value)}
/>
<button onClick={convert}>Convert to BS</button>
{bsDate && <p>BS Date: {bsDate}</p>}
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}Usage with Next.js
This package is pure ESM and works in both the App Router and Pages Router.
// app/page.js (App Router — server component)
import { todayBs, formatBsDate } from 'nepali/date';
import { getAllProvinces } from 'nepali/province';
export default function Page() {
const today = todayBs();
const provinces = getAllProvinces({ lang: 'en' });
return (
<main>
<h1>Today in BS: {formatBsDate(today, 'YYYY MMMM DD')}</h1>
<ul>
{provinces.map(p => (
<li key={p.name}>{p.name} — {p.capital}</li>
))}
</ul>
</main>
);
}If you use the Pages Router with require(), add this to next.config.js:
// next.config.js
const nextConfig = {
experimental: {
esmExternals: true,
},
};
module.exports = nextConfig;Usage with plain Node.js
// ESM (recommended)
import { adToBs, todayFormatted } from 'nepali/date';
import { getAllProvinces } from 'nepali/province';
console.log(adToBs(2024, 4, 13));
// { year: 2081, month: 1, day: 1 }
console.log(todayFormatted());
// '२०८२ बैशाख १४'
console.log(getAllProvinces({ lang: 'en' }).map(p => p.name));
// ['Koshi Pradesh', 'Madhesh Pradesh', ...]// CJS — if your project uses require()
const { adToBs } = await import('nepali/date');API Reference
nepali/date
Import from 'nepali/date':
import { adToBs, formatBsDate, todayBs, ... } from 'nepali/date';adToBs(year, month, day)
Convert a Gregorian (AD) date to Bikram Sambat.
| Parameter | Type | Description |
|-----------|------|-------------|
| year | number | AD year (e.g. 2024) |
| month | number | AD month, 1–12 |
| day | number | AD day, 1–31 |
Returns { year: number, month: number, day: number }
Throws TypeError if inputs are not integers.
Throws RangeError if date is before 1944-01-01 or beyond supported range.
adToBs(2024, 4, 13) // { year: 2081, month: 1, day: 1 }
adToBs(2000, 1, 1) // { year: 2056, month: 9, day: 17 }
adToBs(1997, 10, 5) // { year: 2054, month: 6, day: 19 }formatBsDate(date, format?)
Format a BS date object into a localised string.
| Token | Output | Example |
|-------|--------|---------|
| YYYY | 4-digit year in Devanagari | २०८१ |
| MM | 2-digit month in Devanagari | ०१ |
| DD | 2-digit day in Devanagari | ०१ |
| MMMM | Full Nepali month name | बैशाख |
| MMM | Romanized English month name | Baisakh |
Returns string. Default format is 'YYYY-MM-DD'.
const date = adToBs(2024, 4, 13); // { year: 2081, month: 1, day: 1 }
formatBsDate(date) // '२०८१-०१-०१'
formatBsDate(date, 'YYYY MMMM DD') // '२०८१ बैशाख ०१'
formatBsDate(date, 'DD MMMM YYYY') // '०१ बैशाख २०८१'
formatBsDate(date, 'MMM DD, YYYY') // 'Baisakh ०१, २०८१'
formatBsDate(date, 'YYYY/MM/DD') // '२०८१/०१/०१'todayBs()
Returns today's date as a BS date object.
Returns { year: number, month: number, day: number }
todayBs() // { year: 2082, month: 1, day: 14 } (example)todayFormatted(format?)
Shortcut — returns today's BS date as a formatted string.
Default format is 'YYYY MMMM DD'.
Returns string
todayFormatted() // '२०८२ बैशाख १४'
todayFormatted('YYYY-MM-DD') // '२०८२-०१-१४'
todayFormatted('MMM DD, YYYY') // 'Baisakh 14, २०८२'
todayFormatted('DD MMMM YYYY') // '१४ बैशाख २०८२'isValidBsDate(bsYear, bsMonth, bsDay)
Returns true if the given BS date values form a valid date.
Useful for validating form inputs and date pickers.
Returns boolean
isValidBsDate(2081, 1, 31) // true
isValidBsDate(2081, 1, 32) // false — exceeds days in that month
isValidBsDate(2081, 13, 1) // false — invalid month
isValidBsDate(2081, 0, 1) // false — invalid month
isValidBsDate(1999, 1, 1) // false — before supported range
isValidBsDate(2100, 1, 1) // false — after supported rangegetCurrentNepaliDate(format?)
Today's BS date as a formatted string. Default format is 'YYYY-MM-DD'.
getCurrentNepaliDate() // '२०८२-०१-१४'
getCurrentNepaliDate('YYYY MMMM DD') // '२०८२ बैशाख १४'getCurrentNepaliDay()
Today's BS day number in Devanagari.
getCurrentNepaliDay() // '१४'getCurrentNepaliMonth()
Today's BS month name in Nepali.
getCurrentNepaliMonth() // 'बैशाख'getCurrentNepaliYear()
Today's BS year in Devanagari.
getCurrentNepaliYear() // '२०८२'getCurrentNepaliDayOfWeek()
Today's weekday name in Nepali.
getCurrentNepaliDayOfWeek() // 'सोमवार'getDaysInBsMonth(bsYear, bsMonth)
Returns the number of days in a specific BS month. Unlike the Gregorian calendar, BS month lengths vary year to year.
Throws RangeError if year or month is out of range.
getDaysInBsMonth(2081, 1) // 31
getDaysInBsMonth(2000, 1) // 30
getDaysInBsMonth(2081, 9) // 29getDaysInBsYear(bsYear)
Returns the total number of days in a BS year.
getDaysInBsYear(2081) // 365
getDaysInBsYear(2000) // 365getMonthNames(lang?)
Returns all 12 BS month names.
| lang | Output |
|--------|--------|
| 'ne' (default) | Devanagari |
| 'en' | Romanized English |
getMonthNames() // ['बैशाख', 'जेठ', 'असार', 'साउन', ...]
getMonthNames('en') // ['Baisakh', 'Jestha', 'Ashadh', 'Shrawan', ...]getDayNames(lang?)
Returns all 7 weekday names, starting from Sunday.
getDayNames() // ['आइतवार', 'सोमवार', 'मङ्गलवार', ...]
getDayNames('en') // ['Aaitabar', 'Sombar', 'Mangalbar', ...]toNepaliDigits(n)
Converts any number or numeric string to Devanagari digits.
toNepaliDigits(2081) // '२०८१'
toNepaliDigits('123') // '१२३'
toNepaliDigits('2081-01') // '२०८१-०१'nepali/province
Import from 'nepali/province':
import { getAllProvinces, getDistricts, ... } from 'nepali/province';All functions accept an optional { lang: 'ne' | 'en' } option.
Default is 'ne' (Nepali Devanagari).
getAllProvinces(opts?)
Returns all 7 provinces with their capital, cities, and districts.
Returns Province[]
getAllProvinces()
// [{ name: 'कोशी प्रदेश', capital: 'बिराटनगर', cities: [...], districts: [...] }, ...]
getAllProvinces({ lang: 'en' })
// [{ name: 'Koshi Pradesh', capital: 'Biratnagar', cities: [...], districts: [...] }, ...]getProvinceDetails(name, opts?)
Returns full details of a single province by its English name.
Lookup is case-insensitive. Returns null if not found.
Returns Province | null
getProvinceDetails('Koshi Pradesh', { lang: 'en' })
// {
// name: 'Koshi Pradesh',
// capital: 'Biratnagar',
// cities: [{ name: 'Biratnagar', zipCode: '56613', type: 'metropolitan' }, ...],
// districts: ['Taplejung', 'Panchthar', ...]
// }
getProvinceDetails('unknown') // nullgetCapital(name, opts?)
Returns the capital of a province. Returns null if province not found.
getCapital('Gandaki Pradesh') // 'पोखरा'
getCapital('Gandaki Pradesh', { lang: 'en' }) // 'Pokhara'
getCapital('Unknown') // nullgetDistricts(name, opts?)
Returns all districts of a province. Returns [] if not found.
getDistricts('Gandaki Pradesh', { lang: 'en' })
// ['Kaski', 'Tanahu', 'Lamjung', 'Gorkha', ...]
getDistricts('Gandaki Pradesh')
// ['कास्की', 'तनहुँ', 'लमजुङ', 'गोरखा', ...]getCities(name, opts?)
Returns all metropolitan and sub-metropolitan cities of a province.
zipCode is in Devanagari digits by default.
Returns { name: string, zipCode: string, type: 'metropolitan' | 'sub-metropolitan' }[]
getCities('Bagmati Pradesh', { lang: 'en' })
// [
// { name: 'Kathmandu', zipCode: '44600', type: 'metropolitan' },
// { name: 'Lalitpur', zipCode: '44700', type: 'metropolitan' },
// ...
// ]getZipcode(cityName)
Returns the zip code for a city in Devanagari digits.
Lookup is case-insensitive. Returns null if not found.
getZipcode('Kathmandu') // '४४६००'
getZipcode('Pokhara') // '३३७००'
getZipcode('kathmandu') // '४४६००' (case-insensitive)
getZipcode('Unknown') // nullgetAllMetropolitanCities(opts?)
Returns all 6 metropolitan cities across Nepal with their province.
getAllMetropolitanCities({ lang: 'en' })
// [
// { name: 'Biratnagar', zipCode: '56613', province: 'Koshi Pradesh' },
// { name: 'Birgunj', zipCode: '44300', province: 'Madhesh Pradesh' },
// { name: 'Kathmandu', zipCode: '44600', province: 'Bagmati Pradesh' },
// { name: 'Lalitpur', zipCode: '44700', province: 'Bagmati Pradesh' },
// { name: 'Bharatpur', zipCode: '44200', province: 'Bagmati Pradesh' },
// { name: 'Pokhara', zipCode: '33700', province: 'Gandaki Pradesh' },
// ]getAllSubMetropolitanCities(opts?)
Returns all sub-metropolitan cities across Nepal with their province.
getAllSubMetropolitanCities({ lang: 'en' })
// [
// { name: 'Dharan', zipCode: '56700', province: 'Koshi Pradesh' },
// { name: 'Itahari', zipCode: '56600', province: 'Koshi Pradesh' },
// ...
// ]getProvinceByDistrict(districtName, opts?)
Find which province a district belongs to.
Lookup is case-insensitive. Returns null if not found.
Returns { name: string, capital: string } | null
getProvinceByDistrict('Kaski')
// { name: 'गण्डकी प्रदेश', capital: 'पोखरा' }
getProvinceByDistrict('Kaski', { lang: 'en' })
// { name: 'Gandaki Pradesh', capital: 'Pokhara' }
getProvinceByDistrict('Unknown') // nullgetProvinceNames(opts?)
Returns a flat list of all 7 province names.
getProvinceNames()
// ['कोशी प्रदेश', 'मधेश प्रदेश', 'बागमती प्रदेश', ...]
getProvinceNames({ lang: 'en' })
// ['Koshi Pradesh', 'Madhesh Pradesh', 'Bagmati Pradesh', ...]getDistrictNames(opts?)
Returns a flat list of all 77 district names across Nepal.
getDistrictNames()
// ['ताप्लेजुङ', 'पाँचथर', 'इलाम', ...]
getDistrictNames({ lang: 'en' })
// ['Taplejung', 'Panchthar', 'Ilam', ...]TypeScript
This package ships with full TypeScript definitions. No @types/ package needed.
import { adToBs, formatBsDate, isValidBsDate } from 'nepali/date';
import type { BsDate } from 'nepali/date';
import { getAllProvinces, getProvinceByDistrict } from 'nepali/province';
import type { Province, City, CityType } from 'nepali/province';
const date: BsDate = adToBs(2024, 4, 13);
const formatted: string = formatBsDate(date, 'YYYY MMMM DD');
const valid: boolean = isValidBsDate(2081, 1, 31);
const provinces: Province[] = getAllProvinces({ lang: 'en' });Migration from v1
| v1 | v2 |
|----|----|
| require('nepali/dates') | import ... from 'nepali/date' (no trailing s) |
| convertADToNepaliDate(y, m, d) | adToBs(y, m, d) (old name still works, deprecated) |
| formatNepaliDate(date, fmt) | formatBsDate(date, fmt) (old name still works, deprecated) |
| getCapital(name, false) | getCapital(name, { lang: 'en' }) |
| getDistricts(name, false) | getDistricts(name, { lang: 'en' }) |
| getZipcode(city) returns '' | Returns null when not found |
Supported Range
| Calendar | Range | |----------|-------| | AD input | 1944-01-01 → ~2043-04-12 | | BS output | 2000 Poush 17 → 2099 Chaitra (last day) |
Dates outside this range throw a RangeError.
License
MIT © Anish Gyawali
