ua-plates
v1.0.0
Published
Tiny zero-dependency parser for Ukrainian vehicle registration plates: Cyrillic-lookalike normalization, format/type detection (civilian, police, military, diplomatic, trailer, temporary, vanity) and region decoding by series.
Maintainers
Readme
ua-plates
Tiny zero-dependency TypeScript/ESM parser for Ukrainian vehicle registration plates: normalization of Cyrillic-lookalike spellings, format & type detection (civilian, trailer, police, military, diplomatic, temporary, vanity) and region decoding by the two-letter series.
Built for trustcar.info — a free Ukrainian license-plate encyclopedia. See any plate live at trustcar.info/plate/AA1234BC.
Ukrainian plates only use the 12 letters whose glyphs exist in both Cyrillic and Latin (А В С Е Н І К М О Р Т Х = A B C E H I K M O P T X), so the same plate gets typed both ways. This library folds everything to one canonical Latin form and decodes what the series means. The series → region map was verified against ~180k real registrations from the official data.gov.ua vehicle register, not just copied from reference tables.
Install
npm install ua-platesQuickstart
import { parsePlate, isValidPlate, normalizePlate, regionBySeries } from "ua-plates";
normalizePlate("ах 1234 ор"); // "AX1234OP" (Cyrillic → Latin, uppercase, no separators)
parsePlate("АА 1234 ВС");
// {
// normalized: "AA1234BC",
// valid: true,
// format: "2015",
// type: "civilian",
// series: "AA",
// digits: "1234",
// region: { code: "AA", uk: "м. Київ", en: "Kyiv" }
// }
parsePlate("АВ 5936 ХР").type; // "trailer" (X-suffixes are reserved for trailers)
parsePlate("Т1 0079 АН").type; // "temporary" (T0–T9 dealer/transit series)
parsePlate("D123456").type; // "diplomatic"
isValidPlate("5012"); // false (bare fleet number, not a plate)
regionBySeries("КІ"); // { code: "KI", uk: "Київська обл.", en: "Kyiv Oblast" }API
| Export | Signature | Description |
|--------|-----------|-------------|
| normalizePlate | (raw: string) => string | Pure text transform: trim, drop separators (spaces/hyphens/dots/underscores), uppercase, map the 12 Cyrillic lookalikes to Latin. No validation. |
| parsePlate | (raw: string) => ParsedPlate \| null | Full parse: { normalized, valid, format, type, series, digits, region }. Returns null for empty input or characters that can never appear on a plate; returns { valid: false, ... } for alphanumeric strings that match no known structure. |
| isValidPlate | (raw: string) => boolean | Shortcut for parsePlate(raw)?.valid === true. |
| regionBySeries | (series: string) => { code, uk, en } \| null | Resolve a two-letter series (Latin or Cyrillic, any case) to its region. |
| UA_PLATE_REGIONS | readonly { codes, uk, en }[] | The full series → region dataset: 27 regions, 54 codes (first + second series). |
Recognized formats and types
| Pattern (normalized) | format | type | Example | Notes |
|---|---|---|---|---|
| LL dddd LL | 2015 | civilian | AA1234BC | DSTU 4278:2004 standard (2015 redesign kept the layout). Region from the first pair. |
| LL dddd XL | 2015 | trailer | AB5936XP | X-starting suffixes (XX, XT, XP, XO…) are reserved for trailers/semi-trailers. |
| Td dddd LL | special | temporary | T10079AH | Red dealer/transit plates, series T0–T9 (also the agricultural TP dddd LL). |
| LL dddd L | special | police | AA1234M | Blue National Police plates; region letters first. |
| dddd Ld | special | military | 1234A1 | Armed Forces: four digits + letter + digit. |
| D dddddd, CDP/DP/CC/S + digits | special | diplomatic | D123456, DP12345 | Current D-series and former CDP/DP/CC/S series. |
| ddddd LL | legacy | civilian | 12345KA | 1995 standard («123-45 КА»). |
| dddd LL | legacy | moto | 3678XB | Legacy motorcycle / light-trailer shape. |
| dd LL dddd | legacy | trailer | 05XX5132 | Legacy trailer with numeric region prefix. |
| anything else, 3–8 chars, ≥2 letters | special | vanity | BATMAN | Owner-chosen individual plates (and unclassifiable old plates). |
L = one of the 12 plate letters, d = digit.
Caveats. Plate color isn't part of the string, so text-only classification of police/military/temporary is heuristic — a 7-char vanity plate shaped like LL dddd L will read as police. Modern motorcycle plates use the same LL dddd LL layout as cars (only the physical plate is square), so they parse as civilian; moto is only reported for the legacy shape. A structurally valid plate with an unknown series (e.g. the nationwide II series or future allocations) parses as civilian with region: null.
Region codes
27 regions × 2 series = 54 codes. Second series (K/H/I prefix) were rolled out as regions exhausted their first ranges. IA, IH, KK are allocated but not yet observed in circulation (Cherkasy hasn't exhausted CA; Crimea/Sevastopol issuance froze in 2014).
| Series | Region (uk) | Region (en) | |--------|-------------|-------------| | AA, KA | м. Київ | Kyiv | | AB, KB | Вінницька обл. | Vinnytsia | | AC, KC | Волинська обл. | Volyn | | AE, KE | Дніпропетровська обл. | Dnipropetrovsk | | AH, KH | Донецька обл. | Donetsk | | AI, KI | Київська обл. | Kyiv Oblast | | AK, KK | АР Крим | Crimea | | AM, KM | Житомирська обл. | Zhytomyr | | AO, KO | Закарпатська обл. | Zakarpattia | | AP, KP | Запорізька обл. | Zaporizhzhia | | AT, KT | Івано-Франківська обл. | Ivano-Frankivsk | | AX, KX | Харківська обл. | Kharkiv | | BA, HA | Кіровоградська обл. | Kirovohrad | | BB, HB | Луганська обл. | Luhansk | | BC, HC | Львівська обл. | Lviv | | BE, HE | Миколаївська обл. | Mykolaiv | | BH, HH | Одеська обл. | Odesa | | BI, HI | Полтавська обл. | Poltava | | BK, HK | Рівненська обл. | Rivne | | BM, HM | Сумська обл. | Sumy | | BO, HO | Тернопільська обл. | Ternopil | | BT, HT | Херсонська обл. | Kherson | | BX, HX | Хмельницька обл. | Khmelnytskyi | | CA, IA | Черкаська обл. | Cherkasy | | CB, IB | Чернігівська обл. | Chernihiv | | CE, IE | Чернівецька обл. | Chernivtsi | | CH, IH | м. Севастополь | Sevastopol |
Note the two easy-to-confuse pairs, verified against real registration data: CB = Chernihiv / CE = Chernivtsi (not the alphabetical order you'd guess), and AO = Zakarpattia / AT = Ivano-Frankivsk.
Development
npm install
npm run build
npm testRelated
- trustcar.info — Ukrainian license-plate encyclopedia: look up any plate, VIN checks, reviews (uk/ru/en + 5 more languages)
- API docs: trustcar.info/.well-known/api-catalog
License
MIT © trustcar.info
