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.

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.
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.
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.
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.
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.
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.
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 orderTip: 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.
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.
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.
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 })); // aaabnnThis 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.
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
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
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
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
Guard inputs
Filter non-string values or coerce them with explicit rules to avoid runtime errors.
Tip: Tests matter for edge cases. - 5
Test with real data
Run the function against representative datasets and verify results across environments.
Tip: Include both ASCII and non-ASCII samples.
Prerequisites
Required
- Required
- A modern browser or Node.js environmentRequired
- Basic knowledge of JavaScript arrays and stringsRequired
Optional
- Optional
- Code editor (VS Code, Sublime, etc.)Optional
Keyboard Shortcuts
| Action | Shortcut |
|---|---|
| CopyFrom code blocks | Ctrl+C |
| PasteFrom code blocks | Ctrl+V |
| Format codeDepends on editor | Ctrl+⇧+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