Guides

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

Illustration: a row of metal type where the first small letter is carefully swapped for a capital

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().

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →