String.prototype.toLowerCase()
toLowerCase() The toLowerCase() method returns a new string with all alphabetic characters converted to lowercase. This is essential for normalizing user input, performing case-insensitive comparisons, and standardizing data for storage or comparison.
Syntax
str.toLowerCase()
Parameters
toLowerCase() takes no parameters. Since the method works on the entire string at once, there is no need for arguments—it simply walks the string and lowercases every alphabetic character it finds. Numbers, punctuation, and whitespace pass through without any change, which means you can safely call it on any string without worrying about what the string contains.
String Immutability
Remember that strings in JavaScript are immutable. This means toLowerCase() does not modify the original string—it returns a brand new one:
const original = "HELLO";
const lower = original.toLowerCase();
console.log(original); // "HELLO" (unchanged)
console.log(lower); // "hello" (new string)
This behavior is consistent across all string methods and is a fundamental concept to understand. Every string method that appears to “change” a string is actually returning a new one, leaving the original untouched. This immutability guarantee means you can safely pass strings around without worrying about a method call downstream modifying your copy.
Examples
Basic conversion
const greeting = "HELLO World";
console.log(greeting.toLowerCase()); // "hello world"
const acronym = "NASA";
console.log(acronym.toLowerCase()); // "nasa"
Case-insensitive comparison
Lowercasing is the most common way to do case-insensitive string comparisons in JavaScript. Rather than reaching for a regex with the i flag, normalize both sides to the same case before comparing. This approach is readable, predictable, and works even when you don’t control the input casing—think login forms, search queries, and URL matching.
For reliable case-insensitive matching, normalize both strings:
function isAdmin(role) {
return role.toLowerCase() === 'admin';
}
console.log(isAdmin("ADMIN")); // true
console.log(isAdmin("Admin")); // true
console.log(isAdmin("admin")); // true
console.log(isAdmin("user")); // false
Handling special characters and numbers
toLowerCase() preserves numbers and special characters while converting only letters. Digits, punctuation, and symbols are left exactly as-is, which makes it safe to call on email addresses, file paths, and URLs without corrupting the non-alphabetic parts of the string.
const mixed = "Hello123! @World";
console.log(mixed.toLowerCase()); // "hello123! @world"
const email = "USER@EXAMPLE.COM";
console.log(email.toLowerCase()); // "user@example.com"
const path = "/USERS/DOCUMENTS/file.txt";
console.log(path.toLowerCase()); // "/users/documents/file.txt"
Locale-Safe Transformations
For Turkish, Azerbaijani, and certain other locales, standard toLowerCase() produces incorrect results because these languages have case-mapping rules that differ from the default Unicode algorithm. The Turkish dotted “İ” (U+0130) and dotless “ı” (U+0131) are the most frequently encountered examples—their lowercase/uppercase pairs don’t follow the Latin-1 pattern that toLowerCase() assumes. The Turkish dotted “İ” (U+0130) should lower to “i” (not “İ”), but standard toLowerCase() cannot know that without a locale hint:
// Standard toLowerCase - problematic for Turkish
console.log("İSTANBUL".toLowerCase()); // "istanbul" (wrong)
// Use toLocaleLowerCase for locale-specific conversion
console.log("İSTANBUL".toLocaleLowerCase('tr-TR')); // "istanbul" (correct)
console.log("İSTANBUL".toLocaleLowerCase('en-US')); // "istanbul"
When in doubt about international users, prefer toLocaleLowerCase() with an explicit locale or let JavaScript use the user’s default locale. If your audience is exclusively English-speaking or you are normalizing identifiers and keys (not user-facing text), toLowerCase() is the simpler and faster choice.
Common Patterns
Normalize and trim user input
function normalizeInput(input) {
return input?.trim().toLowerCase() ?? '';
}
console.log(normalizeInput(" HELLO ")); // "hello"
console.log(normalizeInput(null)); // ""
Create URL-friendly slugs
Converting titles and headings into URL-safe slugs is a pattern that depends on toLowerCase(). Slugs must be lowercase by convention (most web servers treat paths case-sensitively), so lowercasing is the first step before stripping whitespace and special characters. This technique is used by static site generators, CMS platforms, and blogging engines to create clean, predictable URLs from article titles:
function slugify(title) {
return title
.toLowerCase()
.trim()
.replace(/\s+/g, '-')
.replace(/[^\w-]/g, '');
}
console.log(slugify("JavaScript Tips & Tricks")); // "javascript-tips-tricks"
toLowerCase() vs toLocaleLowerCase()
toLowerCase() is the safest default when you need a simple, predictable transformation that does not depend on user locale. It is perfect for identifiers, internal comparisons, and data cleanup where the exact same input should always produce the same lowercase output.
When human language rules matter, toLocaleLowerCase() may be a better fit because it can honor locale-specific casing rules. That matters most for text shown to users in languages with special mappings. The key idea is to choose the method based on whether you are normalizing application data or respecting natural language.
Common usage patterns
You will often call toLowerCase() right after trim() so user input is both clean and normalized. That combination is common in login forms, search boxes, and slug generation because it removes superficial differences before comparison. It also pairs well with includes() and indexOf() when you need case-insensitive matching.
Keep the raw value around if the original capitalization matters later. Lowercasing is a one-way formatting step, so it should usually happen at the edge of comparison or storage, not as the only copy of the user input.
Key Behaviors
- Returns a new string—original remains unchanged (immutability)
- Only affects Unicode letters; numbers, symbols, and whitespace are preserved
- Works across all Unicode planes, including emoji
- For locale-specific rules, use
toLocaleLowerCase(locale)
See Also
- String.prototype.localeCompare() — Compare strings locally
- String.prototype.trim() — Remove whitespace