gabrieldevro / romania-geo-data
All 42 Romanian counties and 13,755 localities with SIRUTA codes, postal codes, diacritics and search. JSON, CSV and SQL data plus a tiny PHP API. Official open data (INS + Posta Romana).
Package info
github.com/Gabrieldevro/romania-geo-data
Language:Python
pkg:composer/gabrieldevro/romania-geo-data
Requires
- php: ^8.1
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^10.5|^11.5|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
All 42 Romanian counties and 13,755 localities — with SIRUTA codes, postal codes, proper diacritics and disambiguated labels — as JSON, CSV, SQL, plus a tiny search API for JavaScript and PHP.
Toate județele și localitățile din România, cu coduri SIRUTA, coduri poștale și diacritice corecte. Gata pentru formularele de checkout.
Every Romanian shop needs a county → city dropdown. Most copies floating around have no diacritics, broken ş/ș characters, no way to tell apart the 11 villages called Valea Mare, and no postal codes. This one is built from the official open data with a reproducible script.
import { county, localities, search } from 'romania-geo-data'; county('IS'); // { code: 'IS', name: 'Iași', region: 'Nord-Est', seat: 'Iași', ... } localities('CJ').length; // 434 search('valea mare', { county: 'AG' })[0].label; // "Valea Mare (com. Priboieni)" search('bucuresti')[0].label; // "București, Sectorul 1"
What you get
data/counties.json |
42 counties: plate code (AB…VN, B), name, SIRUTA, development region, county seat, number of localities |
data/localities.json |
13,755 localities: SIRUTA, name, label, county, type, urban/rural, parent commune/town/municipality, postal code |
data/localities.min.json |
compact [siruta, name, county, label, postal_code] arrays (850 KB) for the browser |
data/*.csv |
the same as CSV (UTF-8) |
data/romania.sql |
CREATE TABLE + INSERTs for MySQL, MariaDB, PostgreSQL and SQLite |
A locality looks like this:
{
"siruta": 179560,
"name": "Voluntari",
"label": "Voluntari",
"county": "IF",
"type": "oraș",
"urban": true,
"uat_siruta": 179551,
"uat_name": "Voluntari",
"uat_type": "oraș",
"postal_code": "077190",
"street_level_postal_codes": false
}
labelis ready for dropdowns: villages that share a name get their commune in brackets —Fetești (com. Scobinți).type:municipiu,oraș,sector,localitate componentăorsat.postal_codeis filled for 13,688 localities. Big cities (Iași, Cluj-Napoca, Bucharest sectors…) have one code per street, so it isnullthere andstreet_level_postal_codesistrue.- Names use the correct comma-below
șțand modernâspelling (Câmpuri, notCîmpuri).
JavaScript / TypeScript
npm install romania-geo-data
import { counties, county, localities, locality, search, byPostalCode, normalize } from 'romania-geo-data'; counties(); // all 42, sorted by name county('Bistrita-Nasaud'); // by code or name, diacritics optional localities('B'); // the 6 Bucharest sectors locality(179560); // by SIRUTA search('chis', { limit: 5 }); // exact > prefix > substring, cities before villages byPostalCode('077190'); // [Voluntari] normalize('Bistrița-Năsăud'); // "bistrita-nasaud"
Works in Node 18+. In the browser, import the JSON directly: import data from 'romania-geo-data/data/localities.min.json'. Types are included.
PHP / Laravel
composer require gabrieldevro/romania-geo-data
use Gabrieldev\RomaniaGeo\RomaniaGeo; RomaniaGeo::counties(); RomaniaGeo::county('IS')['name']; // "Iași" RomaniaGeo::localities('CJ'); RomaniaGeo::search('valea mare', 'AB'); RomaniaGeo::byPostalCode('077190');
Laravel seeder in three lines:
foreach (array_chunk(RomaniaGeo::localities(), 1000) as $chunk) { DB::table('localities')->insert(array_map(fn ($l) => Arr::only($l, ['siruta', 'name', 'label', 'county', 'postal_code']), $chunk)); }
Or import RomaniaGeo::path('romania.sql') directly into your database.
Dependent dropdown example
<select id="county"></select> <select id="city"></select> <script type="module"> import { counties, localities } from 'https://cdn.jsdelivr.net/npm/romania-geo-data/+esm'; const c = document.querySelector('#county'), l = document.querySelector('#city'); c.innerHTML = counties().map((x) => `<option value="${x.code}">${x.name}</option>`).join(''); const fill = () => (l.innerHTML = localities(c.value).map((x) => `<option value="${x.siruta}">${x.label}</option>`).join('')); c.onchange = fill; fill(); </script>
Sources and rebuilding
| Source | Publisher | Licence |
|---|---|---|
| SIRUTA – administrative units and localities | Institutul Național de Statistică | OGL-ROU-1.0 |
| Coduri poștale cu SIRUTA – postal codes (Infocod) | Poșta Română | OGL-ROU-1.0 |
pip install xlrd
python tools/build.py # downloads the sources and regenerates data/
These are the latest editions published on data.gov.ro. Administrative changes since then are rare; if you spot one, open an issue or a PR against tools/build.py.
🇷🇴 Pe scurt, în română
Lista completă cu cele 42 de județe și 13.755 de localități din România, din datele oficiale INS (SIRUTA) și Poșta Română (coduri poștale), în JSON, CSV și SQL:
- diacritice corecte (
ș,țcu virgulă,âmodern); - etichete clare pentru satele cu același nume:
Valea Mare (com. Priboieni); - cod poștal pentru 13.688 de localități; orașele mari au cod pe stradă;
- căutare fără diacritice (
iasi→ Iași), pentru JavaScript și PHP/Laravel.
Perfect pentru selectorul județ → localitate din checkout.
License
Code: MIT © Gabriel Dev. Data: © INS and Poșta Română, published under the Open Government Licence Romania 1.0; attribution is kept above.
If it saved you an afternoon of data cleaning, a ⭐ helps other developers find it.