The NATO Phonetic Alphabet: Origins and Everyday Uses
Learn why spelling alphabets exist, how the ICAO/NATO code words were chosen, and how to read codes and passwords aloud accurately, with tested JavaScript and Python.

Anyone who has read a serial number down a bad phone line knows the problem. You say "B" and the other person writes "D". You say "M" and they hear "N". You say "S" and they type "F", then you both spend two minutes on a licence key that should have taken ten seconds. The fix is not to speak louder. The fix is to replace each letter with a word that is hard to confuse with any other word. That is what the NATO phonetic alphabet does, and it has done it reliably for decades. This guide explains where the alphabet came from, how the 26 code words and the digit words were chosen, where people use it today, how to read out passwords and codes without causing errors or leaks, and how to build a converter in JavaScript and Python. It is written for developers, support engineers, sysadmins and anyone who reads codes aloud for a living.
What the NATO phonetic alphabet is
The NATO phonetic alphabet is a spelling alphabet. It assigns one code word to each letter of the Latin alphabet, so that a letter can be communicated by speaking a whole word instead of a single sound. "Alfa" stands for A, "Bravo" for B, "Charlie" for C, and so on to "Zulu" for Z. The same family of procedures also covers the digits, which have their own special pronunciations.
Despite the name, NATO did not invent it and does not control it. The alphabet is standardised by the International Civil Aviation Organization (ICAO), the United Nations agency that sets international rules for civil aviation. Other international bodies for telecommunications and shipping adopted the same code words, and military alliances, NATO among them, use it in their procedures. That is how it picked up a name that is shorter than "the ICAO radiotelephony spelling alphabet" and also slightly misleading. In this guide, "NATO alphabet", "ICAO alphabet" and "international radiotelephony spelling alphabet" all mean the same list of words.
The word "phonetic" is a little loose
Linguists use "phonetic alphabet" for systems such as the International Phonetic Alphabet, which has symbols for speech sounds. The NATO list is not that. It does not describe sounds, and it does not give you pronunciations for arbitrary words. It is a list of 26 ordinary-looking words used as labels. The more precise term is a spelling alphabet, a category described in the Wikipedia article on spelling alphabets. Many such alphabets have existed, differing by country, trade and era. The NATO one is simply the one that won worldwide use.
Why a spelling alphabet is needed at all
Spoken letters are acoustically poor. Many of them sound alike, and the confusion is worst exactly where it hurts most.
- The "E-set" in English. B, C, D, E, G, P, T, V and Z all end in a similar vowel sound. The consonant that tells them apart is short, soft and easily lost to noise.
- Nasal pairs. M and N differ mainly in the closure of the lips versus the tongue, which a narrow telephone channel blurs.
- Fricatives. F and S, and sometimes the letter X, lose their high-frequency energy on a low-bandwidth channel. A traditional telephone line carries only a limited slice of the audible range, so the hissing sounds that distinguish them are weak.
- Cross-language differences. The English name for the letter "J" is not the French one, and the English "G" resembles the French "J". Spanish, German and Dutch speakers pronounce many letter names differently again.
- Accents and stress. Speakers who learned English as a second language, or who have a strong regional accent, may produce letter names that a listener trained on another accent misreads.
Noise makes all of this worse. Radio static, engine hum, a call centre in the background, a poor mobile connection or a hearing difficulty each remove part of the signal. A single short syllable has little redundancy, so losing a piece of it means losing the whole letter. A multi-syllable word such as "Foxtrot" carries redundancy. Even if you lose a syllable or two, there is usually only one code word that fits what remains. That is the core idea: spend more time speaking each symbol so the listener has more evidence to decide with.
A short history of spelling alphabets
Spelling alphabets are older than radio. The need appeared whenever people had to relay exact text through an unreliable spoken or signalled channel. This section outlines the main stages. Where exact dates or details are uncertain, the text says so, because the history is full of near-duplicate lists and partial adoptions, and it is easy to over-claim.
Telegraph and early telephone
Telegraph operators and early telephone users spelled out names and codes using ordinary words, usually names or places, chosen locally and informally. These were habits, not standards, and they differed from office to office. The idea that each letter should have a fixed, agreed word was already present, but there was no common list.
Military signalling before and during the First World War
Armies needed exact messages over field telephones and early wireless sets. British signalling practice before and during the First World War used a letter-word scheme often described as "Ack, Beer, Charlie, Don, Edward" and similar. Some of those words survive in everyday English by an odd route. The term "ack-ack" for anti-aircraft fire and the phrase "pip-emma" for p.m. come from spoken signaller names for the letters A and P and for the letters P and M. They are a reminder that these were working conventions in daily use, not paper standards.
Radio and the interwar standards
The growth of radio telegraphy and later radiotelephony created demand for international agreement. International telecommunications conferences in the 1920s considered spelling alphabets. A widely cited list from that period used place names for the letters, such as city names, and was meant to be understood across many languages. Different organisations also kept their own lists, so an aircraft pilot, a ship's radio operator and an army signaller could each use a different word for the same letter. The exact content and dates of those interwar lists are the kind of detail worth checking in a dedicated history, so treat the summary here as a sketch.
The Second World War
During the war, Allied forces used the same radios and had to coordinate. The United States and the United Kingdom each had spelling alphabets, and they were not identical. The American "Able, Baker, Charlie, Dog, Easy, Fox" set is perhaps the best known and appears in many films and memoirs of the period. The British lists had their own variants. Joint operations made the mismatch plain: if one side says "Able" and the other expects "Ack", an operator loses time. After the war, the pressure for a single list grew strongly in civil aviation, where crews and controllers of many nationalities talk to each other every day.
The post-war ICAO work
In the years after the war, ICAO worked toward a single alphabet for international civil aviation. The goal was to find code words that speakers of different languages could recognise and pronounce. Researchers tested candidate words with speakers from several language backgrounds and compared how often each word was misheard. The result was a list adopted by ICAO around the early 1950s, followed by a modification to a few words. The details are well documented in the Wikipedia article on the NATO phonetic alphabet, which is a good place to read the full timeline, including which of the original candidate words were dropped and why. The version in use today is the result of that revision, and it has not changed in the decades since.
Other bodies then aligned with the list. Maritime and telecommunications organisations adopted the same code words, and military alliances, including NATO, adopted it for their own procedures. NATO's role in popularising the alphabet is the reason for the name most people use.
What stayed constant
Across all those lists, the principle stayed the same. Choose words rather than sounds. Choose words that are distinct from each other. Fix the list so everyone uses the same one. The modern list is better than its predecessors mainly because it was tested across languages rather than designed around English alone.
The code words and digit words
Here is the full list, generated by the code later in this guide. The spellings below are the official ICAO spellings. Two of them look wrong to English readers, and both are deliberate.
| Letter | Code word | Typical pronunciation (ICAO style) |
|---|---|---|
| A | Alfa | AL-fah |
| B | Bravo | BRAH-voh |
| C | Charlie | CHAR-lee (or SHAR-lee) |
| D | Delta | DELL-tah |
| E | Echo | ECK-oh |
| F | Foxtrot | FOKS-trot |
| G | Golf | GOLF |
| H | Hotel | hoh-TELL |
| I | India | IN-dee-ah |
| J | Juliett | JEW-lee-ETT |
| K | Kilo | KEY-loh |
| L | Lima | LEE-mah |
| M | Mike | MIKE |
| N | November | no-VEM-ber |
| O | Oscar | OSS-cah |
| P | Papa | pah-PAH |
| Q | Quebec | keh-BECK |
| R | Romeo | ROW-me-oh |
| S | Sierra | see-AIR-rah |
| T | Tango | TANG-go |
| U | Uniform | YOU-nee-form (or OO-nee-form) |
| V | Victor | VIK-tah |
| W | Whiskey | WISS-key |
| X | X-ray | ECKS-ray |
| Y | Yankee | YANG-key |
| Z | Zulu | ZOO-loo |
The pronunciations are the commonly published guide forms. Capital letters mark the stressed syllable. Treat them as guidance rather than an exact phonetic transcription, since real speakers vary.
Why "Alfa" and "Juliett"
The spellings Alfa and Juliett are the two that trip up English speakers and spell checkers. The reasons are practical.
- Alfa uses "f" instead of "ph". Speakers of several languages would not know that "ph" is meant to sound like "f", and might say it with a separate p sound and an h. Spelling it with an f lets a reader pronounce it correctly with no knowledge of English spelling rules.
- Juliett has two t letters. The word comes from the French pronunciation of the name, and in French a single final t is silent. Without the second t, French speakers would read it as "Julie", which fails the purpose. The double t signals that the final consonant is spoken.
Many people write "Alpha" and "Juliet" anyway. In casual speech that is harmless, because the spoken word is almost identical. In formal documents, training material and software that validates against the standard list, use the official spellings.
The digits
Digits are also at risk of confusion, and in noisy conditions "five" and "nine" can blur, as can "three" and "free". The ICAO procedures therefore give the digits special pronunciations. The written words are ordinary, but the speaker is taught to say them in a modified way.
| Digit | Written word | Spoken form (ICAO style) |
|---|---|---|
| 0 | Zero | ZEE-roh |
| 1 | One | WUN |
| 2 | Two | TOO |
| 3 | Three | TREE |
| 4 | Four | FOW-er |
| 5 | Five | FIFE |
| 6 | Six | SIX |
| 7 | Seven | SEV-en |
| 8 | Eight | AIT |
| 9 | Nine | NIN-er |
Four digits stand out. Three becomes "tree" because the "th" sound does not exist in many languages and is often replaced by a "t" or "s". Four gets a drawn-out first syllable ("fower"), which separates it from "for" and from "five" over a noisy line. Five is "fife", which gives it a clear final consonant and removes the vowel quality it shares with "nine". Nine becomes "niner", which separates it from the German word "nein" (no) and gives it a distinct second syllable. Pilots and controllers use these forms routinely. In everyday IT support, most people simply say the plain English digit, and that usually works because the context makes the situation less hostile than a noisy radio.
The ICAO procedures also include words for punctuation-like items and number structure, such as "decimal" for a decimal point and "hundred" and "thousand" in particular pronunciations, which matter mainly to aviation phraseology. They are outside the scope of a general alphabet converter, which is why the converter later in this guide handles punctuation with simple, clearly labelled substitutes instead of claiming official status for them.
Design criteria: why these words
The ICAO selection process did not pick words at random, and it did not rely on taste. The published criteria can be summarised in a handful of points. They are worth understanding because they explain why informal replacements often do worse.
- Recognisable in many languages. Each word should be familiar, or at least pronounceable, to speakers of the major languages used in international aviation. Names and place words such as Lima, Quebec, Tango and India travel well.
- Easy to pronounce. The word should not demand sounds that are rare. This is why "Alfa" avoids the "ph" and why harder candidates were dropped.
- Acoustically distinct. No two code words should sound alike, even with part of the sound lost. Distinctness is measured at the level of the whole word, with different vowels, different stress patterns and different lengths.
- Distinct initial letter that matches the stress. The word must begin with the letter it represents, and the first syllable should be emphasised enough that the initial letter is clear.
- Not too short. Single-syllable words give little redundancy. Most of the list has two or three syllables for that reason, with exceptions such as "Golf" and "Mike", which are distinct enough on their own.
- Free of offensive or confusing meanings. A word that means something rude or alarming in a major language is a poor choice.
You can see criterion 3 at work if you compare pairs that sound alike when spoken as letters, then look at their code words. "B" and "D" become "Bravo" and "Delta", which share almost nothing. "M" and "N" become "Mike" and "November", which differ in length, vowels and consonants. "F" and "S" become "Foxtrot" and "Sierra". The code words turn a small acoustic difference into a large one.
What the criteria rule out
This is the reason ad hoc lists fail. A word such as "Boy" for B and "Dog" for D shares the same vowel quality. "Sugar" for S and "Shoe" for something similar would collide. Words from your own cultural circle, such as local city names, may be unknown to the listener. And funny or clever words, such as "Ninja" or "Zebra" for fixed letters, may be easy for you to remember and hard for a stranger to decode. The list works because it is fixed. The listener already knows the whole set, so each word is recognised against a closed vocabulary of 26 items. That is far easier than recognising an arbitrary word.
How it works in practice: a worked example
The procedure for reading text aloud is simple.
- Say each character in order.
- For a letter, say the code word.
- For a digit, say the digit word, using the special pronunciation where the listener may need it.
- Say case and punctuation explicitly where they matter.
- Pause briefly between groups.
- Ask the listener to read back what they wrote.
Take the code K7Q-m2Xz. Spoken in full:
Kilo, Seven, Quebec, Dash, lowercase Mike, Two, uppercase X-ray, lowercase Zulu.
The converter code later in this guide produces the base words for you:
Kilo Seven Quebec Dash Mike Two X-ray Zulu
Notice what the converter output does not carry: the case of each character. The alphabet itself has no concept of uppercase and lowercase, so in a case-sensitive code you must add it in speech. A common pattern is to say "capital" or "uppercase" before a letter and "lowercase" or nothing for the default. Agree on the convention at the start of the call. "I will say capital before an uppercase letter and nothing before lowercase" is a clear opening sentence.
Reading back is part of the protocol
A spelling alphabet reduces errors, it does not remove them. The second half of reliable communication is the read-back. After you speak a code, the listener says it back in their own words, using the same alphabet. If they say "Kilo Seven Quebec Dash Mike Two X-ray Zulu", you know the message arrived intact. If they say "Kilo Seven Quebec Dash November...", you know where it went wrong. Pilots and controllers read back clearances for this reason. Support staff can borrow the habit with no cost.
Grouping long codes
Long strings are easier in chunks. A 25-character licence key is usually shown in groups of five, separated by dashes. Read each group, pause, then read the next. Pausing helps the listener's memory, and it gives them a place to catch up if they fall behind. If the code does not come in groups, create them. Four or five characters per group matches the way people hold items in short-term memory.
Where the alphabet is used
The list was built for aviation, but the problem it solves is universal.
Aviation
Pilots and air traffic controllers use it for call signs, taxiways, runway holding points and waypoint names. Airport taxiways are labelled with letters, and the instruction "taxi via Alfa, hold short of Bravo" avoids confusion between similar-sounding letters. Weather information broadcasts at many airports carry a letter code that changes with each update, and pilots acknowledge by saying "information Kilo" or whichever letter is current. This is the alphabet's home territory, and the procedures around it are formal.
Maritime and radio
Ships use the same words on marine radio to spell vessel names, call signs and positions. Amateur radio operators use it constantly to give call signs, often with their own habits for local variation. The alphabet is also used in the international signal flags in the sense that each flag corresponds to a letter and has a spoken name from the same list, which means a crew can say the name of a flag and everyone knows which one is meant.
Military and emergency services
Armed forces use the alphabet for call signs, grid references, unit names and brevity codes, and so do many police, fire and ambulance services. Dispatchers spell out registration plates and street names with it. A number plate such as "LB05 DNT" becomes "Lima Bravo Zero Five Delta November Tango", which is hard to mishear even over a noisy radio in a moving vehicle. In emergencies, speed matters, but a wrong letter costs more time than careful spelling.
Customer service and IT support
This is where most developers meet it. Call centres use it for confirming surnames, postcodes, booking references, account numbers and email addresses. A support engineer may need a customer's licence key, a serial number from the back of a device or a reference number from an error dialog. All of these mix letters and digits, and many contain characters that look and sound alike.
Reading codes, keys and passwords aloud
Software activation keys, recovery codes, Wi-Fi passwords, device pairing codes and one-time reference numbers are all read aloud at some point. The alphabet is the standard remedy. The section on safety below covers when you should and should not do this.
Everyday life
People use it informally when spelling a name for a hotel reservation, a rental car, a doctor's office or a delivery address. You do not need to know the official list perfectly. A partial attempt still helps when the person recognises the words, though see the mistakes section below for why a fixed official list is better.
Reading passwords and codes safely
Speaking a secret out loud has a cost. The alphabet fixes the accuracy problem, but it does nothing for the confidentiality problem. A few rules reduce both risks.
First decide whether you should say it at all
If you can avoid speaking a secret, avoid it. Prefer a channel that carries the text exactly: a password manager's secure share feature, an encrypted message, or a one-time link that expires. Typing is exact. Speech is not. For anything that grants lasting access, a spoken channel is a poor choice.
Consider these situations separately.
- Long-lived passwords. Do not read them aloud to anyone, including a support agent. Legitimate support teams generally do not ask for your password. A request for one is a warning sign.
- One-time codes. Codes sent by text or authenticator app exist to prove that you control the device. Reading one to a stranger who called you is a classic fraud pattern, because the caller is using your code in a login of their own at the same moment. Do not read out one-time codes to anyone who contacted you first.
- Activation keys and serial numbers. These are usually low-sensitivity, and reading them to a vendor is normal. Make sure you called the vendor, not the other way around.
- Temporary passwords you generated for a colleague. If a spoken handover is the only option, use a temporary value that expires or must be changed at first login.
If you must read a secret aloud
- Check who you are talking to. Call back on a number you already trust, not one a caller gave you.
- Check who can overhear. Open offices, trains, speakerphones and recorded lines all leak. Move somewhere private, or write the secret and pass it in another way.
- Use the alphabet and say case. Agree the convention, as described above.
- Split the secret across channels where it is sensible. Read part of it, and send the rest through a different route.
- Rotate it afterwards. Anything spoken on an open line should be treated as exposed. Change it once the task is done.
- Do not store the transcript. If calls are recorded, assume the recording contains the secret.
Why passwords that survive being read aloud are a design choice
If a code will be read aloud by people, its designer can help. Avoid ambiguous characters in the alphabet of the code itself. Many systems intentionally exclude the letters O and I and the digits 0 and 1 from generated codes for exactly this reason. A code built from an unambiguous set is easier to speak, to transcribe and to type, at no loss in practical strength if the code is long enough. If you maintain a system that generates codes humans must read, this is one of the cheapest usability improvements available.
Common mistakes and pitfalls
The alphabet is simple, and that makes mistakes easy to overlook. These are the ones that cause the most trouble.
Informal variants
Speakers often replace official words with their own. "A for Apple", "B for Boy", "S for Sugar" and "M for Mary" are common, and each person's version differs. The listener has no way to know which list you have in mind. If you say "M for Mary" to someone expecting Mike, they may be confused for a moment, and in a noisy channel they may misjudge the word entirely. Stick to the official list unless both sides have agreed on something else.
Mixing national alphabets
Different countries have their own spelling alphabets for telephone use. Germany, for instance, has a standard city-and-name list used on the phone, and other countries have similar ones. A person raised with one list will often fall back on it by reflex. Mixing lists within one spelled word, such as "Alfa, Berta, Charlie", is the worst case, because the listener cannot tell which system governs the next letter. If the other party uses a national list and you do not know it, ask them to use the NATO list or follow theirs for the whole code.
Ambiguous characters in the code itself
Even a perfect spoken alphabet cannot fix an ambiguous printed character. The most common clashes are:
| Characters | Where it goes wrong | What to do |
|---|---|---|
| O and 0 | The letter and the digit look nearly identical in many fonts | Say "Oscar" for the letter and "Zero" for the digit, and mention which is which if unsure |
| I, l and 1 | Capital i, lowercase L and digit one look alike in sans-serif fonts | Say "India", "Lima" and "One", and check the font if the reader is unsure |
| S and 5 | Similar shapes in some typefaces | Say "Sierra" and "Five" |
| B and 8 | Similar shapes in small print | Say "Bravo" and "Eight" |
| Z and 2 | Similar shapes in handwriting | Say "Zulu" and "Two" |
| U and V | Close in some stylised fonts | Say "Uniform" and "Victor" |
The alphabet gives the speaker the right word, but the speaker must first read the character correctly. When the printed code is ambiguous, say so out loud and agree on a way to confirm, such as reading the code from a monospaced rendering or copying and pasting it.
Forgetting case and punctuation
The alphabet carries no case. A code like aB3d has four characters, two of which are lowercase and one uppercase, and the spoken words "Alfa Bravo Three Delta" contain none of that. Say "lowercase Alfa, uppercase Bravo, Three, lowercase Delta". For symbols, name them clearly: "dash", "underscore", "at sign", "dot" or "stop", and "slash". Say "dash" for a hyphen, and be clear whether you mean a hyphen or an underscore. Email addresses and URLs are full of these.
Speaking too fast
Speed erases the benefit. The alphabet works because each word is a distinct unit, and a rushed stream of words blurs together. Keep a steady, slightly slower pace, and pause between groups.
Inventing words on the fly
Under pressure, people grab the first word that comes to mind. "Z for Zebra" is fine as a joke and fine in a quiet room. In a noisy channel it adds risk. Memorise the official 26. They take an hour to learn and last a lifetime.
Mispronouncing the special digits
Saying "niner" to a listener who does not know the convention may cause confusion rather than clarity. Use the aviation digit pronunciations when both people know them. With the general public, plain digits spoken slowly are usually better.
Treating the alphabet as encryption
The alphabet is a spoken aid. It does not hide anything. It converts text into a longer text, and the longer text can be reversed by anyone who knows the list, which is everybody.
Accessibility and multilingual notes
A spelling alphabet is an accessibility tool as well as an engineering one, and it has limits worth knowing.
People with hearing loss
Hearing loss often reduces perception of high-frequency consonants first, which are the sounds that separate many letters. A word with several vowels and consonants gives a listener with partial hearing more cues than a single syllable. The alphabet helps, though it does not replace other accommodations such as written text, text relay services or video calls where lip reading is possible. When you offer to spell a code, offer to send it in writing as well.
Speakers of other languages
The words were chosen to be pronounceable across major languages, but they are not neutral. A speaker whose language lacks some sounds will still alter them. "Whiskey" starts with a sound that some speakers find hard. "Charlie" begins with a sound that is "sh" in some pronunciations. The aviation list tolerates a range of pronunciations because the word set is closed. The listener decodes the closest match, not an exact sound.
Languages with different scripts
The alphabet covers only the Latin letters A to Z. It has no entries for accented letters such as é, ñ, ü, å or ø, for letters of other scripts, or for the many non-Latin writing systems. If you need to spell a name with an accent, say the base letter and then describe the accent in words, such as "E, acute accent". In practice, forms and systems that accept only the 26 basic letters often strip the accents anyway, and a converter has to decide what to do with them. The code later in this guide takes the simple route of decomposing an accented letter and spelling the base letter.
Screen readers and written text
If you display code words on a web page or in an app, a few details help screen reader users.
- Keep each code word as a separate word in the text, so it is announced clearly.
- Do not rely on colour or layout alone to show which letter a word belongs to. Put the letter next to it, as in "A: Alfa".
- If you show a long converted string, put each group in its own element, or separate groups with a clear delimiter, so that it can be navigated.
- Provide the output as selectable text, not an image.
Cultural cautions
A few of the words have everyday meanings that vary. "Romeo" and "Juliett" are names, "Golf" and "Tango" are an activity and a dance, and "Charlie" is a common name. None of that causes trouble in normal use, though the list was designed so that no word has a harmful meaning in the languages considered. For internal tools used in a particular language community, a quick check with local colleagues costs nothing.
Building a converter: the algorithm
Converting text to code words is a small problem with several decisions in it. Make those decisions deliberately and write them down. The DevUtilX tool and the code below follow the same approach.
The core loop
For each character in the input:
- Normalise it so that accented letters decompose into a base letter plus a combining mark.
- Drop the combining marks.
- Convert to uppercase for lookup.
- If it is one of the 26 letters, emit the code word.
- If it is a digit, emit the digit word.
- If it is a known punctuation mark, emit its label.
- Otherwise emit a placeholder, or skip it, according to the option chosen.
Everything else is a refinement of these steps.
Decisions you must make
Case. The alphabet has no case, so the code word for "a" and "A" is the same. A converter can either discard case, which is simplest, or mark it, for example with a prefix such as "lowercase" or "capital". Discarding is fine for names and serial numbers that are case-insensitive. Mark it for passwords and keys that are case-sensitive.
Digits. Choose between plain words ("Three", "Nine") and the ICAO pronunciation ("Tree", "Niner"). Plain words are friendlier for general use. The special form is right for aviation-style communication. A good converter offers both.
Spaces. A space in the input separates words, such as a first name and a surname. Emit a visible marker, such as "(space)", so the output keeps its structure, or emit a line break, or skip it. A marker avoids the subtle error of two names being spelled as one run of letters.
Punctuation. The alphabet defines no words for most punctuation. Choose plain labels, such as "Dash", "Underscore", "At", "Slash" and "Stop" for a full stop, and document that these are conventions. Do not present them as official.
Unknown characters. Characters such as currency signs, emoji or letters from other scripts have no entry. Options are to emit a placeholder such as "?", to skip them, or to raise an error. Silent skipping is the most dangerous, because the listener will write down a shorter code than the speaker intended. A visible placeholder makes the gap obvious.
Accented letters. Unicode normalisation form NFD splits "ë" into "e" followed by a combining diaeresis. Removing combining marks then leaves the base letter. This is a reasonable default for names. Say so in the interface, because the original spelling is not fully preserved. The Wikipedia article on Unicode equivalence explains the normalisation forms. Some letters, such as "ø" and "ß", do not decompose, so they fall through to the unknown rule unless you add explicit mappings.
Empty input. Return an empty list rather than an error.
Reverse conversion
Going from words back to letters is a dictionary lookup, with a few practical wrinkles:
- Split the input on whitespace.
- Compare case-insensitively.
- Accept both the digit words and the ICAO digit pronunciations.
- Accept common alternative spellings, such as "Alpha", "Juliet" and "Xray", since people type them. Treat them as input variants only, never as output.
- Decide what to do with unrecognised words. A placeholder is better than skipping, for the same reason as before.
- Note that markers such as "(space)" and punctuation labels need handling if you want the round trip to be lossless. A simple reverse converter that covers letters and digits only is often enough.
Complexity
Both directions are linear in the length of the input. Each character requires one dictionary lookup. No dictionary is large, so there is nothing to optimise. The real work is in the decisions above, not the loop.
JavaScript implementation
The following module was written and run in Node.js to verify the behaviour shown. It exports a forward converter and a reverse converter.
const LETTERS = {
A: "Alfa", B: "Bravo", C: "Charlie", D: "Delta", E: "Echo", F: "Foxtrot",
G: "Golf", H: "Hotel", I: "India", J: "Juliett", K: "Kilo", L: "Lima",
M: "Mike", N: "November", O: "Oscar", P: "Papa", Q: "Quebec", R: "Romeo",
S: "Sierra", T: "Tango", U: "Uniform", V: "Victor", W: "Whiskey",
X: "X-ray", Y: "Yankee", Z: "Zulu",
};
const DIGITS = {
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine",
};
const SPOKEN = {
0: "Zero", 1: "Wun", 2: "Too", 3: "Tree", 4: "Fower",
5: "Fife", 6: "Six", 7: "Seven", 8: "Eight", 9: "Niner",
};
const PUNCT = {
".": "Stop", "-": "Dash", "_": "Underscore",
"@": "At", "/": "Slash", " ": "(space)",
};
function toNato(text, { spoken = false, punct = true, unknown = "?" } = {}) {
const out = [];
const base = text.normalize("NFD").replace(/[̀-ͯ]/g, "");
for (const ch of base) {
const up = ch.toUpperCase();
if (LETTERS[up]) out.push(LETTERS[up]);
else if (/[0-9]/.test(ch)) out.push((spoken ? SPOKEN : DIGITS)[ch]);
else if (punct && PUNCT[ch]) out.push(PUNCT[ch]);
else out.push(unknown);
}
return out;
}
const REV = {};
for (const [k, v] of Object.entries(LETTERS)) REV[v.toLowerCase()] = k;
for (const t of [DIGITS, SPOKEN]) {
for (const [k, v] of Object.entries(t)) REV[v.toLowerCase()] = k;
}
Object.assign(REV, { alpha: "A", juliet: "J", xray: "X" });
function fromNato(words) {
return words.trim().split(/\s+/).map((w) => REV[w.toLowerCase()] ?? "?").join("");
}
Running it on several inputs gave this output:
toNato("Hi5") -> Hotel India Five
toNato("AB-12 x") -> Alfa Bravo Dash One Two (space) X-ray
toNato("Zoë 90", {spoken: true}) -> Zulu Oscar Echo (space) Niner Zero
toNato("a€b") -> Alfa ? Bravo
fromNato("Hotel India Fife") -> HI5
fromNato("Alpha Bravo Wun Too Niner") -> AB129
toNato("O0 lI1") -> Oscar Zero (space) Lima India One
Several details are worth studying. The accented "ë" in "Zoë" became "Echo", because the decomposition step stripped the diaeresis. The euro sign had no entry and became a visible "?". The reverse conversion accepted "Fife" and "Niner" as well as "Alpha", which is not the official spelling. And the last line shows why the alphabet matters for ambiguous characters: the input O0 lI1 is nearly unreadable in many fonts, but the output tells the listener exactly which character is which.
Notes on the JavaScript
for (const ch of base)iterates by Unicode code point, so characters outside the basic plane do not split into halves. An emoji produces one?, not two.toUpperCaseis locale-independent here. Be careful with letters such as the Turkish dotless i if you ever switch to locale-aware conversion.- The regular expression
[̀-ͯ]covers the main block of combining diacritical marks, which is enough for typical Latin-script names. normalize("NFD")is documented on MDN.
Python implementation
The Python version follows the same design. It was run with Python 3 and produced the same results as the JavaScript version.
import unicodedata
LETTERS = dict(zip("ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett Kilo Lima "
"Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whiskey "
"X-ray Yankee Zulu".split()))
DIGITS = dict(zip("0123456789",
"Zero One Two Three Four Five Six Seven Eight Nine".split()))
SPOKEN = dict(zip("0123456789",
"Zero Wun Too Tree Fower Fife Six Seven Eight Niner".split()))
PUNCT = {".": "Stop", "-": "Dash", "_": "Underscore",
"@": "At", "/": "Slash", " ": "(space)"}
def to_nato(text, spoken=False, punct=True, unknown="?"):
digits = SPOKEN if spoken else DIGITS
decomposed = unicodedata.normalize("NFD", text)
stripped = "".join(c for c in decomposed if not unicodedata.combining(c))
out = []
for ch in stripped:
up = ch.upper()
if up in LETTERS:
out.append(LETTERS[up])
elif ch in digits:
out.append(digits[ch])
elif punct and ch in PUNCT:
out.append(PUNCT[ch])
else:
out.append(unknown)
return out
REVERSE = {v.lower(): k for k, v in LETTERS.items()}
for table in (DIGITS, SPOKEN):
REVERSE.update({v.lower(): k for k, v in table.items()})
REVERSE.update({"alpha": "A", "juliet": "J", "xray": "X"})
def from_nato(words):
return "".join(REVERSE.get(w.lower(), "?") for w in words.split())
A short test harness, run in the sandbox, printed:
Hotel India Five
Alfa Bravo Dash One Two (space) X-ray
Zulu Oscar Echo (space) Niner Zero
Alfa ? Bravo
HI5
AB129
Oscar Zero (space) Lima India One
roundtrip ok
The last line comes from an assertion that from_nato(" ".join(to_nato("K7QM2XZ"))) returns the original string. That round trip holds for letters and digits. It does not hold when the input includes spaces or punctuation, because the markers "(space)" and "Dash" are not looked up by the reverse function, so they come back as ?. If you need a lossless round trip for such input, extend the reverse table with the punctuation labels and handle "(space)" as a token.
Notes on the Python
unicodedata.combiningreturns a non-zero value for combining marks, which is more robust than a hard-coded character range. The module is documented in the Python standard library reference.str.upperhandles a few special cases, such as the German "ß" becoming "SS". In this converter "ß" would become "SS" and then, as two characters in a string, would not match a single key, so it falls through to the unknown rule. Test any character that matters to you.- Python strings are sequences of code points, so iteration is by character, as in the JavaScript version.
Testing your own converter
A useful test suite is short.
- All 26 letters, in lower and upper case, produce the expected word.
- All 10 digits produce the expected word in both modes.
- The two tricky spellings,
AandJ, produce "Alfa" and "Juliett". - Accented input such as "é" produces the base letter's word.
- Unknown input such as "€" produces the placeholder, never nothing.
- Round trip on letters and digits returns the original, uppercased.
- Empty input returns an empty result.
If your converter is part of a larger code base, keep the word table in one place and import it. Duplicated tables drift apart, and a typo in one copy is exactly the kind of bug that goes unnoticed. When you need to compare two versions of a table or two converter outputs, a diff helps. Our guide to comparing files and code diffs covers the practical tools, and our guide on JavaScript code formatting best practices is useful if you are tidying a module like the one above.
Step-by-step: spell text with DevUtilX
For a quick job, you do not need to write code. The DevUtilX Text to NATO Alphabet tool converts any text into code words in your browser.
- Open the Text to NATO Alphabet tool.
- Type or paste the text you want to spell, such as a name, a serial number or a reference code.
- Read the code words that appear. Each letter becomes its code word, and digits appear as digit words.
- Check any characters the tool flags as unsupported, and decide how to say them in plain words.
- Copy the result, or read it directly from the screen to the person on the call.
- Ask the listener to read the code back.
The text is processed locally in your browser and is not uploaded, which matters when you are spelling account numbers or internal identifiers. That said, the safety rules above still apply. A tool that keeps data private does not make it safe to read a long-lived secret over an open phone line, so use the tool for accuracy and use your judgement about confidentiality.
A few practical habits make the tool more useful.
- Spell short, high-risk pieces, not entire paragraphs. Use it for the surname, the postcode, the licence key or the reference number, not the whole message.
- Keep the tool open during a call. Paste the code once, then read from the output, which avoids misreading a font while you speak.
- Remember the case. The alphabet does not carry it, so add it in speech when the code is case-sensitive.
- Check ambiguous characters in the source. If the original has an
land a1you cannot tell apart, fix that before you convert.
Performance, security and privacy considerations
A text-to-code-word converter is computationally trivial, so the considerations are mostly about behaviour at the edges.
Performance
Conversion is linear in the input length, and the lookup tables are tiny. For typical inputs, the cost is negligible in any language. If you convert very large texts, build the output with a list and join once at the end, as the examples do, instead of repeated string concatenation. Avoid regular expressions inside the loop when a simple dictionary lookup will do. If a page converts text live as the user types, run the conversion on each input event without debouncing for short inputs. Debounce only if you render a long result and the browser starts to lag.
Security
The converter handles text, which often contains secrets. Three points apply.
- Keep it client-side where you can. A converter that sends your input to a server turns a harmless helper into a data-collection point. Browser-only processing avoids the problem entirely.
- Do not log inputs. If you build a server-side version, avoid writing request bodies to logs. Spelled-out secrets in logs are as exposed as the secrets themselves.
- Escape on output. If you insert converted text into HTML, treat it as data, not markup. Placeholders that echo unknown characters can carry angle brackets or quotes from the input. Use
textContentinstead ofinnerHTML.
Privacy and the spoken channel
Spoken text is easy to record and overhear. Do not assume that a phonetic spelling makes the content safe, and remember that anything spelled over a recorded support line is on the recording.
Accessibility in the interface
Label inputs and outputs clearly, provide the result as real text, and make the copy action reachable by keyboard. If the converter updates live, announce changes politely, for example through an element marked aria-live="polite", so screen reader users know that new output is available without losing their place.
Troubleshooting guide
When spelling goes wrong, work from symptom to cause to fix.
Symptom: the listener keeps writing the wrong letter
Cause. You are spelling with informal words, or speaking too fast, or the line is too noisy for the words you picked.
Fix. Switch to the official list, slow down, and ask for a read-back. If the line is bad, offer to send the code in writing.
Symptom: the listener asks "is that the letter O or the number zero?"
Cause. The spoken alphabet has separate words for them, but the speaker said only "oh".
Fix. Say "Oscar" for the letter and "Zero" for the digit every time. Never say "oh" for zero in a code.
Symptom: the code is rejected even though the spelling was read back correctly
Cause. Case was lost. The alphabet does not carry uppercase or lowercase, and the code is case-sensitive.
Fix. Add "capital" and "lowercase" in speech, or send the code as text. If you control the system, consider generating case-insensitive codes.
Symptom: the converter outputs a question mark in the middle of the result
Cause. The input contains a character with no entry, such as a symbol, an emoji or a letter from another script.
Fix. Say that character in plain words. If you maintain the converter, add a mapping or document the limitation.
Symptom: an accented name loses its accent
Cause. The converter decomposes accented letters and keeps only the base letter.
Fix. Spell the base letter and then name the accent, such as "E, acute". If accents matter for the data you are recording, record them in writing as well.
Symptom: the reverse conversion returns question marks for spaces and dashes
Cause. The reverse table covers letters and digits only, and the forward output contains markers such as "(space)" and "Dash".
Fix. Add the punctuation labels to the reverse table, handle "(space)" as a token, or strip the markers before reversing.
Symptom: "Alpha" is accepted but "Alfa" is rejected, or the other way round
Cause. The input validator uses one spelling. Users type both.
Fix. Accept both spellings on input and always produce the official spelling on output.
Symptom: a validator complains that "Juliet" is wrong
Cause. The checker is strict about the official double-t spelling.
Fix. If strictness is not needed, accept both. If you must be strict, tell users the official spelling is "Juliett".
Symptom: the same code is read differently by two speakers
Cause. They use different digit conventions, one saying "niner" and the other "nine", or "tree" and "three".
Fix. Agree on one convention at the start. With people unfamiliar with aviation phrasing, use plain digits, spoken slowly.
Symptom: the listener cannot keep up with a long code
Cause. The code was read as one long stream.
Fix. Read it in groups of four or five characters, with a pause between groups, and confirm each group before continuing.
Best practices and checklist
These habits apply whether you are a pilot, a support agent or a developer building a tool.
- Use the official list. Learn the 26 words, with the official spellings of Alfa and Juliett.
- Say Oscar and Zero. Never say "oh" for a zero in a code.
- State case and symbols explicitly. Say "capital", "lowercase", "dash", "underscore", "at sign" and "stop".
- Group long codes into chunks of four or five characters, and pause between them.
- Ask for a read-back, in the alphabet, and compare it with the original.
- Prefer a written channel for long or complex codes, and use speech as a backup.
- Never read long-lived secrets or one-time codes to a caller who contacted you.
- Design codes for humans. Exclude look-alike characters from generated codes that people will read aloud.
- Keep the word table in one place in your code, and test it.
- Show unknown characters visibly in a converter, never drop them silently.
- Offer both digit styles in a converter, plain and ICAO.
- Do not claim official status for the punctuation labels, which are conventions.
Before you hand over a code by voice, run through this short list:
- Is speech the right channel, or can I send the text safely?
- Is the other party who they say they are?
- Can anyone overhear or record this?
- Have I agreed on how to say case, digits and symbols?
- Have I grouped the code into chunks?
- Did the listener read it back correctly?
- If it was a secret, have I planned to change it afterwards?
Comparison: ways to communicate a code
The NATO alphabet is one tool among several. This table shows how it compares with the alternatives for reading a code to someone.
| Method | Accuracy over noisy channels | Learning effort | Works across languages | Best for |
|---|---|---|---|---|
| Plain letter names | Low | None | Poor, letter names differ | Quiet rooms, short, forgiving codes |
| NATO / ICAO alphabet | High | Low to moderate | Good, designed for it | Radio, phone, any noisy or international channel |
| Informal "A for Apple" words | Moderate, varies by speaker | None | Poor, depends on local words | Casual spelling of a name in a quiet setting |
| National spelling alphabets | High among users of that list | Moderate | Poor outside that country | Domestic telephone use in that country |
| Written message or email | Very high | None | Very good | Anything long, mixed or sensitive |
| Copy and paste via a secure share | Very high, exact | Low | Very good | Passwords, keys and tokens |
| QR code or link | Very high | Low | Very good | Pairing, activation and onboarding flows |
| Reading digits in groups only | Moderate | None | Moderate | Numeric codes without letters |
The lesson from the table is that the alphabet is best when speech is the only channel. When a written or machine-readable channel is available, use it, because it is exact. Combine the two where it helps: send the code in writing and offer to spell it aloud if the reader has a problem.
Further details worth knowing
Why Quebec and Papa have stress marks in guides
Two words have pronunciations that surprise English speakers. Quebec is pronounced "keh-BECK", in the French style, and Papa is "pah-PAH", with the stress on the second syllable. The guide forms in the table show these. If you stress them in the usual English manner, you may still be understood, though the closed list helps the listener infer the word.
How "Charlie", "Uniform" and "Whiskey" show flexibility
The official guides allow more than one pronunciation for some words. "Charlie" can start with either a "ch" or an "sh" sound. "Uniform" can begin with "you" or "oo". This is a deliberate allowance for speakers of different languages. It also shows the design principle at work: the word needs to be recognisable, not pronounced identically by everyone.
The role of context
The alphabet works partly because both sides expect it. A listener who has been told "I will spell this with the NATO alphabet" is primed. A listener who hears "Whiskey" unprompted may still understand it from context, though not always. Saying that you will spell the word helps the listener switch mode.
A note on numbers in other contexts
If your communication includes phone numbers, dates and times, the digit conventions can matter. Say phone numbers in groups, in the grouping the listener expects. For dates, say the month as a word, not a number, since formats differ between countries. This is not part of the alphabet, but it solves the same problem of ambiguity across cultures.
FAQ
Is the NATO phonetic alphabet the same as the ICAO alphabet?
Yes, in practice. ICAO standardised the code words for aviation, and other organisations, including NATO, adopted the same list. Different names, same words.
Why is it spelled "Alfa" and "Juliett"?
So that speakers of other languages pronounce them correctly. "Alfa" avoids the English "ph" spelling, and "Juliett" has a double t so that French speakers say the final consonant.
Do I have to use the special digit pronunciations such as "niner"?
Only if the people you are talking to know them. They are standard in aviation and radio work. In everyday support calls, plain digits spoken slowly are usually clearer for the general public.
Does the alphabet include lowercase and uppercase?
No. There is one word per letter, regardless of case. If case matters, say "capital" or "lowercase" before the letter, and agree on the convention at the start.
What do I say for symbols such as dash, underscore and at sign?
The alphabet has no official words for most symbols. Say their plain names clearly, such as "dash", "underscore", "at sign", "dot" or "stop", and "slash". Confirm with a read-back, particularly for email addresses and URLs.
Is it safe to read my password to a support agent using the alphabet?
The alphabet improves accuracy, not security. Do not read long-lived passwords or one-time codes to anyone who contacted you. If you must share a secret by voice, verify who you are talking to, make sure you cannot be overheard, and change the secret afterwards.
How do I tell O from 0 and I from l from 1 when speaking?
Say "Oscar" for the letter O and "Zero" for the digit. Say "India" for capital i, "Lima" for lowercase L and "One" for the digit. If the printed character is truly ambiguous, say so and check it another way.
Can I make up my own words for each letter?
You can, and many people do, but the listener cannot know your list. A fixed, shared list is what makes the system work, so use the official one unless you have agreed on another.
How many words are in the alphabet?
There are 26 letter code words, one for each letter from A to Z, plus the digit words zero to nine and, in aviation procedures, a few extra words for number structure.
Does it work for accented letters and other scripts?
Not directly. It covers the 26 basic Latin letters. For accented letters, say the base letter and describe the accent. For other scripts, use whatever transliteration or spelling method the people involved have agreed on.
Who maintains the alphabet?
ICAO publishes the standard for aviation. It has been stable for a long time, and you should not expect the list to change.
Why do generated codes avoid O, 0, I and 1?
Because they are the characters people most often confuse when reading or typing. Excluding them makes codes easier to read aloud and transcribe.
What should a converter do with a character it does not know?
Show it visibly, for example with a placeholder, and let the user decide how to handle it. Dropping it silently produces a shorter code than the speaker intended.
Is the DevUtilX tool private?
The conversion runs in your browser, and your text is not uploaded. As with any tool, avoid pasting secrets you do not need to share.
Conclusion
The NATO phonetic alphabet is a small, carefully tested piece of engineering for a very human problem. It replaces fragile single-syllable letter names with distinct, internationally recognisable words, and it has proved its value in aviation, shipping, emergency services and every support desk that has ever read a serial number aloud. To use it well, stick to the official list and spellings, say case and symbols explicitly, group long codes, ask for a read-back and keep secrets off open voice channels. If you build tools that handle spelled text, decide how to treat case, digits, punctuation and unknown characters, and never let a converter drop input silently. For a quick conversion with no setup, try the Text to NATO Alphabet tool. To keep going, read our guides on comparing files and code diffs and JavaScript code formatting best practices.


