How to capitalize the first letter — without turning iPhone into Iphone

Open Python and type "iPhone".capitalize(). The answer: "Iphone". The command "make the first letter uppercase" also made every other letter lowercase. And the brand is ruined.
JavaScript has no built-in command for this at all. So everyone writes their own — and almost everyone trips over an empty string, a leading quote or the Turkish "i". Below are six steps to a version that doesn't break.
Step by step: capitalizing the first letter
1. Decide what you actually need.
There are two different tasks with similar names:
- "Upper first":
ivan→Ivan,iPhone→IPhone. Leave the rest alone. - "Capitalize":
iVAN→Ivan. First letter uppercase, the rest lowercase.
In lodash these are _.upperFirst and _.capitalize. Python's capitalize() is the second one. For text people type, you almost always want the first. The second breaks "iPhone", "McDonald" and "NASA".
2. Write the basic version — safely.
The first thing everyone writes:
s[0].toUpperCase() + s.slice(1)
On an empty string this crashes: Cannot read properties of undefined (reading 'toUpperCase'). An empty string has no character zero — it's undefined. And empty form fields happen all the time.
Fix it with one swap — charAt instead of square brackets:
s.charAt(0).toUpperCase() + s.slice(1)
charAt(0) on an empty string returns an empty string, not undefined. Nothing crashes. Why strings behave this way is in what is a string.
3. Skip anything that isn't a letter.
The string "hello" (with quotes) starts with a quote mark. The string ivan starts with spaces. The basic version will dutifully "uppercase" the quote, and nothing changes.
Find the first letter with a regular expression:
s.replace(/\p{L}/u, (ch) => ch.toUpperCase())
\p{L} means "any letter in any alphabet": Latin, Cyrillic, Greek. The u flag is required — without it \p{L} doesn't work. replace without the g flag replaces only the first match, which is exactly what we want.
Check: "hello" → "Hello", ivan → Ivan.
Careful with digits: 2 apples becomes 2 Apples. If your string can start with a number, decide whether you want that. Often it's simpler to strip spaces with trim() and only raise the first character.
4. Account for the language.
In Turkish, the uppercase of i is İ, with a dot. Plain toUpperCase() doesn't know that:
"istanbul".toUpperCase() // "ISTANBUL"
"istanbul".toLocaleUpperCase("tr") // "İSTANBUL"
If your app is multilingual, use toLocaleUpperCase and pass the interface language. For English and Russian there's no difference — but the code will be ready for the rest.
Two more surprises: German ß becomes SS in uppercase — the string length changes. And Dutch ijsselmeer is properly written IJsselmeer, with two capitals. JavaScript can't do that — that's manual work.
5. If it's only for the screen — do it in CSS.
Often you don't need to change the data. You just need it to look right. Then:
.label::first-letter {
text-transform: uppercase;
}
::first-letter works on block elements (p, div, li). Not on a span, unless you make it display: inline-block. The upside: the data stays exactly as it was. The form submits and the database stores the original text.
Don't confuse it with text-transform: capitalize — that raises every word. "Maria de la Cruz" becomes "Maria De La Cruz".
6. Don't correct people's names.
If a user typed van Gogh, McDonald or d'Artagnan, those aren't mistakes. Never apply the "capitalize" from step 1 to names — it wipes out the inner capitals. At most, raise the first letter if the person typed everything in lowercase. The same logic applies to input masks: help, but don't rewrite for the person.
What you end up with
One small function you can drop into any project:
function upperFirst(s, locale = "en") {
return s.replace(/\p{L}/u, (ch) => ch.toLocaleUpperCase(locale))
}
upperFirst("") // ""
upperFirst('"hello"') // '"Hello"'
upperFirst("iPhone") // "IPhone"
upperFirst("istanbul", "tr") // "İstanbul"
It doesn't crash on empty input, skips quotes and spaces, knows about language, and leaves the other letters alone. And for a purely visual task, you have the CSS version.
Why doesn't JavaScript have a built-in capitalize?
Because the rule depends on the language and on the task — see steps 1 and 4. The standard chose to give you building blocks (toLocaleUpperCase, regexes) rather than one function that would be wrong for half the world.
How do I capitalize the first letter of every word?
Add the g flag and a word boundary: s.replace(/(^|\s)\p{L}/gu, (m) => m.toLocaleUpperCase("en")). English title case has its own rules on top (small words like "of" and "the" stay lowercase), so for real headlines a library is easier.
Is it fine to ask an AI?
Yes, but spell out the task. Prompt: "Write an upperFirst function in JavaScript: only the first letter uppercase, leave the rest untouched, must not crash on an empty string, skip leading quotes and spaces." Without those conditions, an AI almost always writes s[0].toUpperCase().
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





