Sort a String JavaScript: A Practical Guide

Learn how to sort strings in JavaScript with both default and locale-aware approaches, including sorting characters, arrays of strings, and robust edge-case handling in 2026.

JavaScripting
JavaScripting Team
·5 min read
Sort Strings in JS - JavaScripting
Quick AnswerDefinition

To sort a string in JavaScript, convert the string to a character array, sort that array, and rejoin it. For simple lexicographic sorting, use [...str].sort().join(''); For case-insensitive or locale-aware results, use a comparator such as (a,b)=> a.toLowerCase().localeCompare(b.toLowerCase()) or a.localeCompare(b, undefined, { sensitivity: 'base' }).

Understanding the problem: sort a string javascript

Sorting strings in JavaScript is a common task, and understanding the basic approach helps you handle more complex scenarios later. At its core, you decide whether you want to sort the raw string by its characters or sort strings that are already tokens. For a single string, you must first break it into components, sort those components, and then reassemble the result. The simplest method sorts characters lexicographically, while more advanced methods use locale-aware comparisons to respect language rules.

JavaScript
const s = "javascript"; const sortedChars = [...s].sort().join(""); console.log(sortedChars); // "aacijprstv"

This approach treats the string as individual characters, which is perfect for character-level sorting.

Why it matters: When you later sort arrays of strings, consistent character-level behavior helps ensure predictable order across environments. To handle mixed content (ASCII and non-ASCII), you will want locale-aware options.

JavaScript
const items = ["éclair","Éclair","cafe","Cafe"]; items.sort((a,b)=> a.localeCompare(b, undefined, { sensitivity: 'base' })); console.log(items); // [ 'cafe', 'Cafe', 'Éclair', 'éclair' ]
  • Variants: use localeCompare for language-aware ordering.
  • Caveats: different environments may yield slightly different results for some locales.

context":"section"}

Sorting characters of a string: char-level ordering

If you need to sort the characters of a string rather than tokens, the fastest approach is to convert the string to an array of characters, sort, and rejoin. This is useful for puzzles, encoding tricks, or preparing data for certain visualization tasks. The simple case uses default lexicographic order; more robust code sorts with a comparator to ensure consistent results.

JavaScript
function sortCharacters(input){ return [...input].sort().join(""); } console.log(sortCharacters("banana")); // "aaabnn" // Case-insensitive, locale-aware variant function sortCharsCI(input){ return [...input].sort((a,b)=> a.toLowerCase().localeCompare(b.toLowerCase())); } console.log(sortCharsCI("BaNana")); // "aABnnn" (example across environments)

Edge considerations: non-Latin scripts may require locale-aware sorting to get intuitive results.

context2":"section"}

Locale-aware and case-insensitive sorting: best practices

When sorting strings, especially user input in multilingual apps, locale-aware comparisons yield more natural results. The localeCompare API supports language and region, plus sensitivity controls. Use a base sensitivity to ignore case and diacritics when you want ignore-case sorting while keeping correct ordering across locales.

JavaScript
const words = ["ångström","Ångström","apple","Apple"]; words.sort((a,b)=> a.localeCompare(b, undefined, { sensitivity: 'base' })); console.log(words); // [ 'apple', 'Apple', 'ångström', 'Ångström' ]

Alternative: combine with toLowerCase for a quick, platform-agnostic approach, but localeCompare is generally safer for real-world data.

context3":"section"}

Custom comparators: sorting by length then alphabetically

Sometimes you need more than a simple lexicographic sort. A common pattern is to sort by length first, and then alphabetically for equal lengths. This requires a comparator that returns the first non-zero difference.

JavaScript
const arr = ["apple","fig","date","banana"]; arr.sort((a,b)=> a.length - b.length || a.localeCompare(b)); console.log(arr); // [ 'fig', 'date', 'apple', 'banana' ]

This pattern can be extended to multiple criteria (e.g., length, then locale-aware order), and you can generalize it into a reusable sortStrings function.

context4":"section"}

Stability and performance considerations: understanding behavior

Array.prototype.sort in JavaScript is typically O(n log n). The actual behavior is implementation-dependent when comparing complex keys. Modern engines (like those in major browsers) provide stable sorts, which preserve the relative order of equal elements. When sorting strings directly, stability matters if you sort by a secondary key after the primary. If you need guaranteed stability across environments, you can attach an index as a tie-breaker.

JavaScript
const items = [ { s: 'repeat', idx: 1 }, { s: 'repeat', idx: 2 }, { s: 'alpha', idx: 3 } ]; items.sort((a,b)=> a.s.localeCompare(b.s) || a.idx - b.idx); console.log(items.map(i => i.idx)); // [3,1,2] in stable scenarios when s ties; index guides final order

Tip: clone your array before sorting to avoid mutating input if immutability is important in your codebase.

context5":"section"}

Sorting arrays of strings by length or other metrics: utilities

A common need is to sort an array of strings by a derived key, such as length or a transformed version of the string. Encapsulating this logic into a small utility function makes your code reusable and testable.

JavaScript
function sortStrings(arr, options = {}){ const { key = s => s, locale = undefined, sensitivity = 'base' } = options; return arr.slice().sort((a,b)=> key(a).localeCompare(key(b), locale, { sensitivity })); } const words = ["apple","fig","date","banana"]; console.log(sortStrings(words, { key: s => s, locale: undefined })); // [ 'apple', 'banana', 'date', 'fig' ]

This approach supports locale-aware sorting on a derived key (e.g., lowercase form) and can be extended to multi-criteria sorting.

context6":"section"}

Sorting a string’s characters in a reusable pattern: final pattern

For many projects, you’ll want a robust, reusable function to sort a string’s characters or a string array with a single API surface. The following example demonstrates a compact, reusable function that supports case-insensitive, locale-aware, and length-based sorting strategies.

JavaScript
function sortString(input, opts = {}){ const { caseSensitive = false, locale = undefined, by = 'char' } = opts; if(by === 'char'){ const comparator = caseSensitive ? (a,b)=> a.localeCompare(b, locale) : (a,b)=> a.toLowerCase().localeCompare(b.toLowerCase(), locale, { sensitivity: 'base' }); return [...input].sort(comparator).join(""); } // by can be 'length' for strings, or extend for more keys return input.split("").sort((a,b)=> a.length - b.length || a.localeCompare(b)).join(""); } console.log(sortString("javascript", { by: 'char', caseSensitive: false })); // aacijprstv console.log(sortString("éclair", { caseSensitive: false, locale: undefined })); // ailcear (depending on locale)

Use this pattern to build robust, parameterized sorting utilities across your projects.

context7":"section"}

Practical takeaways: how to apply these techniques in real projects

  • Always decide whether you need character-level or token-level sorting before coding. This prevents over-engineering.
  • For multilingual data, prefer locale-aware comparisons with localeCompare and consider sensitivity options.
  • When you need stable results, implement a tie-breaker (e.g., original index) to guarantee predictability across environments.
  • Guard against non-string inputs if your function accepts user-provided data; otherwise, you’ll encounter runtime errors.
  • Wrap sorting logic in a reusable function to improve testability and reuse across modules.

context8":"section"}

Putting it all together: a reusable sortString utility with examples

The final pattern combines the insights above into a compact, reusable function that handles common use cases. It demonstrates both character-level and string-array sorting, with optional locale awareness and case handling. This example provides a starting point for real-world projects where text data is user-generated and requires predictable ordering.

JavaScript
function sortString(input, options = {}){ const { mode = 'chars', locale, sensitivity = 'base', caseSensitive = false } = options; if(mode === 'chars'){ const comp = caseSensitive ? (a,b)=> a.localeCompare(b, locale, { sensitivity }) : (a,b)=> a.toLowerCase().localeCompare(b.toLowerCase(), locale, { sensitivity: 'base' }); return [...input].sort(comp).join(""); } // fallback on simple string sorting return input.split("").sort((a,b)=> a.localeCompare(b, locale, { sensitivity })); } console.log(sortString("javascript", { mode: 'chars' })); // aacijprstv console.log(sortString("banana", { mode: 'chars', caseSensitive: true })); // aaabnn

This pattern keeps your code maintainable and adaptable as requirements evolve in 2026 and beyond.

context9":"section"}

Edge-case patterns: handling non-string input safely

Real-world data often contains nulls, undefineds, or non-string values. A robust implementation validates inputs or filters out invalid elements before sorting. The safe path is to convert values to strings or to filter non-strings entirely, depending on your data contract.

JavaScript
function safeSortStrings(arr){ return arr.filter(v => typeof v === 'string') .slice() .sort((a,b)=> a.localeCompare(b)); } console.log(safeSortStrings(["apple", null, "banana", 1])); // ["apple","banana"]

When consuming user-provided data, implement explicit type checks and tests to prevent runtime errors and ensure consistent behavior across environments.

context10":"section"}

Final patterns and checklist

  • Decide between character-level or string-level sorting up front, and choose locale-aware options when dealing with non-ASCII input.
  • Use a stable sort or a tie-breaker to guarantee consistent results across browsers and Node.js.
  • Build small, reusable utilities to simplify code reuse and testing.
  • Validate inputs to prevent runtime errors in production applications.

By following these guidelines, you can reliably sort strings in JavaScript across various locales and data shapes, keeping code clean and predictable across 2026 and beyond.

context11":"section"],

prerequisites({

Steps

Estimated time: 30-60 minutes

  1. 1

    Define input source

    Identify whether you want to sort individual characters or strings in an array. Prepare a clean input array or string for processing.

    Tip: Start with a small example to validate logic.
  2. 2

    Choose sorting strategy

    Decide between default lexicographic sort or locale-aware sorting using localeCompare with appropriate options.

    Tip: Locale-aware sorting handles non-ASCII characters better.
  3. 3

    Implement comparator

    Write a comparator that matches your needs (case sensitivity, locale, and stability).

    Tip: Use a stable strategy or add a tie-breaker.
  4. 4

    Guard inputs

    Filter non-string values or coerce them with explicit rules to avoid runtime errors.

    Tip: Tests matter for edge cases.
  5. 5

    Test with real data

    Run the function against representative datasets and verify results across environments.

    Tip: Include both ASCII and non-ASCII samples.
Pro Tip: Clone arrays before sorting to avoid mutating the original input.
Warning: Sort results can vary by environment for rare locale cases; test in target browsers.
Note: Locale-aware sorting may produce different results across locales; document behavior.
Pro Tip: Encapsulate sorting logic in a reusable function for consistency.

Prerequisites

Required

Optional

Keyboard Shortcuts

ActionShortcut
CopyFrom code blocksCtrl+C
PasteFrom code blocksCtrl+V
Format codeDepends on editorCtrl++V

Questions & Answers

What does sort do by default on strings in JavaScript?

Default Array.prototype.sort sorts elements as strings based on UTF-16 code unit values. This means uppercase letters may come before lowercase, and non-ASCII characters are compared by their code units unless a custom comparator is provided.

By default, strings are ordered according to their character codes, which can place uppercase letters before lowercase and may not align with natural language expectations.

How can I sort strings case-insensitively?

Use a comparator that compares lower (or upper) case representations, or use localeCompare with sensitivity: 'base'. This ensures 'A' and 'a' are treated as equal for sorting purposes.

You can sort ignoring case by converting both sides to the same case or by using localeCompare with base sensitivity.

Is sort stable in all environments?

Sort stability is not guaranteed in all JavaScript environments. Modern engines are stable, but you should verify in your target platform or implement a tie-breaker to preserve original order when keys are equal.

In newer engines, sorts are usually stable, but be careful and test to be safe.

How do I sort a string’s characters alphabetically?

Split the string into characters, sort the array, and join back. This yields a new string with characters in alphabetical order.

To sort the characters inside a string, turn it into characters, sort, then join again.

What about non-string inputs in sorting utilities?

Filter or coerce non-string values before sorting to prevent runtime errors and ensure predictable results.

If you might get non-strings, clean the data first, so sorting behaves reliably.

Can I sort by multiple criteria (length, then alphabetically)?

Yes. Use a comparator that first compares by the primary criterion (e.g., length) and then uses a secondary criterion (e.g., localeCompare) for tie-breakers.

You can sort by length first, then by alphabetical order to get well-defined results.

What to Remember

  • Sort characters by converting to an array and joining back
  • Use localeCompare for locale-aware sorting
  • Guard against non-string inputs for robust code
  • Create reusable sortString utilities for maintainability

Related Articles