nepali_address_plus 0.0.1
nepali_address_plus: ^0.0.1 copied to clipboard
Comprehensive, zero-dependency Nepal administrative division data and lookup utilities — Zone (legacy), Province, District, Local Level, and Ward — sourced and verified against MoFAGA (Ministry of Fed [...]
nepali_address_plus #
Nepal's complete administrative division data — Province, District, Local Level and Ward, plus the legacy Zone hierarchy — with synchronous lookup utilities and zero dependencies.
Province
└── District
└── Local Level (Metropolitan / Sub-Metro / Municipality / Rural Municipality)
└── Ward
- Zero dependencies. Pure Dart,
dart:coreonly. - Synchronous. Every lookup is an in-memory call over
constdata — noFuture, no asset loading, noFutureBuilderin your widget tree. - Runs everywhere. Flutter (all platforms), Dart CLI tools, Dart servers.
- Bilingual. English and Devanagari (नेपाली) names.
- Legacy-aware. Resolves pre-2015 zone records onto today's structure.
Installation #
dart pub add nepali_address_plus
or for Flutter:
flutter pub add nepali_address_plus
Then:
import 'package:nepali_address_plus/nepali_address_plus.dart';
Quick start #
import 'package:nepali_address_plus/nepali_address_plus.dart';
void main() {
// Walk the hierarchy downward.
final bagmati = NepaliAddress.province(3)!;
print('${bagmati.nameEn} (${bagmati.nameNp}) — capital ${bagmati.capital}');
final districts = NepaliAddress.districtsByProvince(bagmati.id);
print('${districts.length} districts');
final kathmandu = NepaliAddress.district(28)!;
final levels = NepaliAddress.localLevelsByDistrict(kathmandu.id);
print('${kathmandu.nameEn}: ${levels.length} local levels');
// Resolve a legacy zone record forward onto today's districts.
final old = NepaliAddress.districtsByZone(5); // Bagmati Zone
print(old.map((d) => d.nameEn).join(', '));
}
Building an address form? See Example app below for a complete cascading picker.
API #
Everything hangs off NepaliAddress, a static-only class. No instantiation,
no setup, no initialization call.
| Member | Returns | Description |
|---|---|---|
provinces |
List<Province> |
All 7 provinces |
province(int id) |
Province? |
Province by id (1–7), or null |
districts |
List<District> |
All 77 districts |
district(int id) |
District? |
District by id (1–77), or null |
districtsByProvince(int provinceId) |
List<District> |
Districts in a province |
zones |
List<Zone> |
All 14 legacy zones |
zone(int id) |
Zone? |
Zone by id (1–14), or null |
districtsByZone(int zoneId) |
List<District> |
Districts that belonged to a zone |
localLevels |
List<LocalLevel> |
All 755 local levels |
localLevel(int id) |
LocalLevel? |
Local level by id, or null |
localLevelsByDistrict(int districtId) |
List<LocalLevel> |
Local levels in a district |
wardsByLocalLevel(int localLevelId) |
List<Ward> |
Wards, derived from wardCount |
Models #
| Type | Fields |
|---|---|
Province |
id, nameEn, nameNp, capital, districtIds |
District |
id, nameEn, nameNp, provinceId, zoneId, headquarter |
Zone |
id, nameEn, nameNp, districtIds |
LocalLevel |
id, nameEn, nameNp?, type, districtId, wardCount?, wardNumbers |
LocalLevelType |
enum: metropolitanCity, subMetropolitanCity, municipality, ruralMunicipality — each with labelEn / labelNp |
Ward |
number, localLevelId |
Store ids, display names #
Persist districtId: 28, not "Kathmandu". Ids are stable across releases;
a spelling correction in a future version won't invalidate saved records.
Data status #
| Tier | Count | Status |
|---|---|---|
| Zone | 14 / 14 | Complete, cross-checked for id coverage |
| Province | 7 / 7 | Complete |
| District | 77 / 77 | Complete, cross-checked for province + zone consistency |
| Local Level | 755 / 755 | Name, type and district assignment complete and verified |
| Local Level — Devanagari names | 0 / 755 | Not yet sourced — nameNp is null |
| Ward counts | 0 / 755 | Not yet sourced — wardCount is null |
| Ward | derived | Available once wardCount is populated |
Read this before calling
wardsByLocalLevel.
nameNpandwardCountonLocalLevelarenullfor every entry today, sowardsByLocalLevel()currently returns an empty list. That is not a bug and it does not mean the place has no wards — it means the value hasn't been verified against an official source yet.These fields are deliberately left
nullrather than guessed. Check fornulland show your own fallback:final level = NepaliAddress.localLevel(322)!; if (level.wardCount == null) { // Not yet sourced — let the user type a ward number instead. } else { final wards = NepaliAddress.wardsByLocalLevel(level.id); }
Local level name/type/district data was derived from official administrative boundary data and cross-matched against this package's 77-district list with zero unmatched rows and zero districts left without a local level. Type counts (6 metropolitan / 11 sub-metropolitan / 277 municipality / 461 rural municipality = 755) match the source's published statistics exactly.
Devanagari names and ward counts still need a verification pass against MoFAGA and the Election Commission of Nepal.
Why "Zone" is included #
Zones (अञ्चल) were abolished in 2015, but older citizenship certificates,
land records and legacy databases still reference them.
NepaliAddress.districtsByZone(id) resolves those old records forward onto
the current province/district structure, so you don't have to maintain a
second lookup table yourself.
Example app #
A Flutter demo lives in
example/
— a cascading Province → District → Local Level → Ward picker, a legacy-zone
migration lookup, and a dataset coverage screen.
cd example
flutter pub get
flutter run # or: flutter run -d chrome
dart run bin/cli_demo.dart # pure Dart, no Flutter needed
Contributing #
Found an inaccurate name, headquarters or mapping? Please open an issue — correctness here matters more than completeness speed.
The dataset is authored as JSON and the Dart is generated from it. See CONTRIBUTING.md for the data format and the workflow for submitting a fix.
License #
MIT — see LICENSE.