Ship internal tools in hours, not weeks. Real auth, users, jobs, audit logs, and cohesive UI included. Early access $249 $499 → [Get it now]

How to convert a string to lowercase in JavaScript

Converting strings to lowercase is fundamental for data normalization, case-insensitive comparisons, email validation, and implementing features like search functionality or consistent data storage in JavaScript applications. With over 25 years of experience in software development and as the creator of CoreUI, I’ve implemented lowercase conversion extensively in components like search filters, email inputs, username processing, and data validation systems where consistent casing ensures reliable functionality. From my extensive expertise, the most reliable and universally supported solution is using the built-in toLowerCase() method. This approach is straightforward, performant, and specifically designed for case conversion with complete browser compatibility.

Use the toLowerCase() method to convert all characters in a string to lowercase.

const text = 'HELLO WORLD'
const lowercase = text.toLowerCase()
// Result: 'hello world'

The toLowerCase() method converts all alphabetic characters in the string to their lowercase equivalents and returns a new string without modifying the original. In this example, 'HELLO WORLD'.toLowerCase() transforms all uppercase letters to lowercase, resulting in 'hello world'. Non-alphabetic characters like numbers, spaces, and punctuation remain unchanged. The method handles international characters correctly, converting accented letters and other Unicode characters to their proper lowercase forms.

1. Case-Insensitive String Comparison

One of the most common uses for toLowerCase() is performing case-insensitive comparisons. Without normalizing case, identical words with different casing would be treated as different values.

const userInput = 'JavaScript'
const expected = 'javascript'

// Direct comparison fails
console.log(userInput === expected)
// Result: false

// Normalize both sides to lowercase
console.log(userInput.toLowerCase() === expected.toLowerCase())
// Result: true

// Practical example: case-insensitive search
const items = ['React', 'Angular', 'Vue', 'Svelte']
const query = 'angular'

const match = items.find(
  item => item.toLowerCase() === query.toLowerCase()
)
// Result: 'Angular'

// Case-insensitive includes check
const hasMatch = items.some(
  item => item.toLowerCase().includes(query.toLowerCase())
)
// Result: true

Always convert both sides of a comparison to the same case. Converting only one side is a common source of bugs. This pattern is essential for implementing search functionality in CoreUI React components where user input must match data regardless of casing.

2. Locale-Specific Conversion with toLocaleLowerCase()

The standard toLowerCase() uses Unicode default case mappings, which can produce incorrect results for certain languages. Use toLocaleLowerCase() when working with locale-sensitive text.

// Turkish has special casing rules for the letter I
const turkishText = 'İSTANBUL'

// Default toLowerCase — incorrect for Turkish
console.log(turkishText.toLowerCase())
// Result: 'i̇stanbul' (incorrect — produces combining dot above)

// Locale-aware conversion — correct for Turkish
console.log(turkishText.toLocaleLowerCase('tr'))
// Result: 'istanbul' (correct)

// German eszett example
const germanText = 'STRAßE'
console.log(germanText.toLowerCase())
// Result: 'straße'
console.log(germanText.toLocaleLowerCase('de'))
// Result: 'straße'

// Safe pattern for multilingual apps
const normalizeText = (text, locale) => {
  if (!text) return ''
  return locale
    ? text.toLocaleLowerCase(locale)
    : text.toLowerCase()
}

console.log(normalizeText('HÉLLO', 'fr'))  // 'héllo'
console.log(normalizeText('HELLO'))         // 'hello'

Use toLocaleLowerCase() when your application handles multilingual content or when correctness for specific locales matters. For English-only applications, toLowerCase() is sufficient and slightly faster.

3. Normalizing User Input

Form data and user input often arrive in inconsistent casing. Normalizing to lowercase before processing prevents duplicates and ensures consistent storage.

// Email normalization
const rawEmail = '  [email protected]  '
const normalizedEmail = rawEmail.trim().toLowerCase()
// Result: '[email protected]'

// Username normalization
const rawUsername = ' JohnDoe123 '
const normalizedUsername = rawUsername.trim().toLowerCase()
// Result: 'johndoe123'

// Normalize form data before submission
const normalizeFormData = (data) => {
  const normalized = { ...data }
  const fieldsToLowercase = ['email', 'username', 'domain']

  fieldsToLowercase.forEach(field => {
    if (typeof normalized[field] === 'string') {
      normalized[field] = normalized[field].trim().toLowerCase()
    }
  })

  return normalized
}

const formData = {
  name: 'John Doe',
  email: '  [email protected]  ',
  username: 'JohnDoe',
  domain: 'Example.Com'
}

console.log(normalizeFormData(formData))
// { name: 'John Doe', email: '[email protected]',
//   username: 'johndoe', domain: 'example.com' }

Notice that name is left unchanged — not all fields should be lowercased. Only normalize fields where casing is irrelevant, like emails and usernames. This is the pattern we use in CoreUI form validation to ensure clean data before submission.

4. Filtering and Searching Arrays

Combining toLowerCase() with array methods creates powerful, case-insensitive filtering for lists, tags, and search results.

const products = [
  { name: 'MacBook Pro', category: 'Laptops' },
  { name: 'iPhone 16', category: 'Phones' },
  { name: 'iPad Air', category: 'Tablets' },
  { name: 'AirPods Pro', category: 'Audio' },
  { name: 'Mac Mini', category: 'Desktops' }
]

// Case-insensitive search across multiple fields
const search = (items, query) => {
  const q = query.toLowerCase()
  return items.filter(item =>
    item.name.toLowerCase().includes(q) ||
    item.category.toLowerCase().includes(q)
  )
}

console.log(search(products, 'mac'))
// [{ name: 'MacBook Pro', ... }, { name: 'Mac Mini', ... }]

console.log(search(products, 'PHONE'))
// [{ name: 'iPhone 16', ... }]

// Deduplicate case-insensitive tags
const tags = ['React', 'react', 'REACT', 'Vue', 'vue', 'Angular']
const uniqueTags = [...new Map(
  tags.map(tag => [tag.toLowerCase(), tag])
).values()]
// Result: ['REACT', 'vue', 'Angular'] (last occurrence wins)

// Case-insensitive sort
const names = ['Charlie', 'alice', 'Bob', 'dave']
names.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
// Result: ['alice', 'Bob', 'Charlie', 'dave']

Convert the search query to lowercase once before the loop rather than inside the callback for better performance with large arrays. For related string operations, see how to check if a string contains a substring in JavaScript.

5. Converting to URL Slugs

Generating URL-friendly slugs requires converting text to lowercase as the first step in the transformation pipeline.

// Basic slug generator
const slugify = (text) => {
  return text
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, '')   // remove non-word chars
    .replace(/\s+/g, '-')        // spaces to hyphens
    .replace(/-+/g, '-')         // collapse multiple hyphens
}

console.log(slugify('How to Convert a String to Lowercase'))
// Result: 'how-to-convert-a-string-to-lowercase'

console.log(slugify('  Hello,  World!  '))
// Result: 'hello-world'

// Advanced slug with transliteration for common accented chars
const advancedSlugify = (text) => {
  const charMap = {
    'à': 'a', 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a',
    'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
    'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i',
    'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o',
    'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
    'ñ': 'n', 'ç': 'c'
  }

  return text
    .toLowerCase()
    .split('')
    .map(char => charMap[char] || char)
    .join('')
    .trim()
    .replace(/[^\w\s-]/g, '')
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-')
}

console.log(advancedSlugify('Crème Brûlée Recipe'))
// Result: 'creme-brulee-recipe'

Slug generation always starts with toLowerCase() because URLs are case-sensitive and conventions dictate lowercase paths. For more on string transformations, see how to replace all occurrences of a string in JavaScript.

6. Building a CSS Class Name Generator

Converting to lowercase is essential when generating CSS class names from dynamic data, ensuring consistent and valid selectors.

// Generate BEM-style class names
const bemClass = (block, element, modifier) => {
  let className = block.toLowerCase()
  if (element) className += `__${element.toLowerCase()}`
  if (modifier) className += `--${modifier.toLowerCase()}`
  return className
}

console.log(bemClass('Card', 'Header', 'Active'))
// Result: 'card__header--active'

console.log(bemClass('NavBar', 'Link'))
// Result: 'navbar__link'

// Convert camelCase or PascalCase to kebab-case
const toKebabCase = (str) => {
  return str
    .replace(/([a-z])([A-Z])/g, '$1-$2')
    .replace(/\s+/g, '-')
    .toLowerCase()
}

console.log(toKebabCase('backgroundColor'))
// Result: 'background-color'

console.log(toKebabCase('BorderTopLeftRadius'))
// Result: 'border-top-left-radius'

// Useful for dynamic style objects to CSS custom properties
const style = {
  fontSize: '16px',
  lineHeight: '1.5',
  letterSpacing: '0.5px'
}

const cssVars = Object.entries(style).map(
  ([key, value]) => `--${toKebabCase(key)}: ${value};`
)
// ['--font-size: 16px;', '--line-height: 1.5;', '--letter-spacing: 0.5px;']

The toKebabCase function is particularly useful when working with CSS-in-JS solutions or mapping JavaScript property names to CSS custom properties. For converting case in the opposite direction, see how to convert a string to uppercase in JavaScript.

Best Practice Note:

This is the same approach we use in CoreUI React components for normalizing user input, implementing case-insensitive search, and processing form data across our component ecosystem. For locale-specific lowercase conversion, use toLocaleLowerCase() which respects language-specific rules like Turkish dotted and dotless i. Always convert strings to the same case before performing comparisons to ensure accurate matching. When working with user input, combine trim() with toLowerCase() to handle both whitespace and casing inconsistencies — see how to trim whitespace from a string in JavaScript.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author