What Kind of Sort Does JavaScript Use?
Discover how JavaScript sorts arrays: default string-based sorting, numeric sorts with a comparator, and practical patterns for objects. Learn pitfalls and best practices to write robust, portable code.

JavaScript sort is a built in array method that sorts the elements of an array in place using an optional comparator; by default it converts elements to strings and sorts lexicographically.
What is JavaScript sort and why it matters
In JavaScript, sorting is a common task that appears in data processing, UI features, and algorithms. The language provides a built in tool for this job: Array.prototype.sort. Importantly, JavaScript does not mandate a single sorting algorithm; the ECMAScript specification defines how the sort operation behaves, not the exact steps the engine must take. This means the outcome should be consistent with how you configure the comparator, but the underlying method may vary between Chrome, Node.js, or other runtimes. For developers, the practical takeaway is straightforward: rely on the sort API's documented behavior and always supply a comparator when you need a predictable order. According to JavaScripting, the right approach to sorting is to understand the default behavior and when to skip it in favor of explicit numeric or custom ordering. With that mindset, you can write robust, portable code that behaves the same in major engines.
How Array.prototype.sort works under the hood
The sort operation acts in place on the array, rearranging its elements and returning the same array for chaining. If you pass a compareFunction, the engine uses it to determine the relative order of any two elements; if you omit it, the engine converts elements to strings and sorts based on Unicode code unit order. The exact sorting algorithm is implementation dependent, and can vary by runtime. The result is deterministic with a given comparator, but performance characteristics are left to the engine. This means the same sort call can behave differently across environments, even with the same input data. In practice, developers should rely on a well chosen comparator and test across environments to ensure consistent results.
The default behavior: string sorting explained with examples
By default, Array.prototype.sort sorts elements by their string representations. This means numbers, booleans, and other values are first converted to strings and then compared in Unicode order. Example:
const nums = [10, 2, 5, 1];
nums.sort();
console.log(nums); // [1, 10, 2, 5]This illustrates how the default lexicographic sort differs from numeric ordering. If you want numeric sorting without a comparator, you can convert to strings or use a different approach; but the standard pattern is to supply a comparator function that performs numeric comparison.
Sorting numbers correctly with a compare function
To sort numbers in ascending order, always provide a numeric comparator:
const nums = [10, 2, 5, 1];
nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 5, 10]Using a comparator ensures the sort uses numeric order rather than lexicographic order. You can adapt the comparator for descending order by returning b - a instead of a - b. This pattern is the de facto standard for numeric sorts in JavaScript.
Sorting strings and locale awareness
String sorting is influenced by case and locale. The default sort is not locale aware, which can yield surprising results for multilingual data. If you need case-insensitive or locale-aware sorting, use LocaleCompare within your comparator:
const words = ['éclair','banana','apple','Álvaro'];
words.sort((a,b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
console.log(words); // [ 'apple', 'Álvaro', 'banana', 'éclair' ]Locale aware sorting helps produce intuitive orders for users in different regions. For complex locales, you can pass additional options to localeCompare to tweak diacritics and case handling.
Sorting objects by keys and multi field sorts
Sorting arrays of objects is a common real world task. You typically compare the object properties inside the comparator. For multi field sorts, combine keys carefully:
const people = [
{ name: 'Ada', age: 29 },
{ name: 'Grace', age: 25 },
{ name: 'Ada', age: 31 }
];
people.sort((a,b) => a.name.localeCompare(b.name) || a.age - b.age);
console.log(people);This sorts by name first and then by age when names tie. When sorting by multiple fields, always consider the correct tie breaking logic to avoid unstable or surprising results.
Stability and engine differences
JavaScript does not enforce sort stability in the ECMAScript standard. Depending on the engine, a sort may be stable or unstable. If your application relies on a particular order for equal keys, explicitly include a tie breaking rule in your comparator or create a secondary sort pass. Always test sorts across engines you target, such as Chrome, Firefox, and Node.js, since behavior can vary with version and runtime.
Best practices and pitfalls
- Always pass a comparator for numeric sorts to avoid string based quirks.
- Remember that sort mutates the original array in place; clone first if you need to preserve the original data.
- For strings, prefer locale aware comparison when appropriate rather than relying on default Unicode code point order.
- When sorting by multiple fields, design a robust comparator that handles all edge cases (nulls, undefined, or missing keys).
- Validate behavior with edge cases like empty arrays, single element arrays, or mixed types to prevent unexpected results.
Performance considerations and testing patterns
Sorting performance depends on array size, the complexity of the comparator, and the engine implementation. While JavaScript engines optimize sort performance, heavy comparator logic can become a bottleneck on large data sets. To ensure robust performance, profile your sort paths in realistic workloads, memoize expensive key extractions, and avoid recomputing keys inside tight loops. For critical paths, consider a dedicated sorting utility that precomputes keys or uses typed arrays when applicable.
Questions & Answers
What does the default sort do in JavaScript?
The default sort converts elements to strings and sorts them in Unicode code unit order. This means numbers may not sort numerically unless you provide a comparator.
The default sort turns elements into strings and sorts them alphabetically. For numbers you need a comparator to get numeric ordering.
How do you sort numbers correctly in JavaScript?
Always pass a numeric comparator, such as (a, b) => a - b, to Array.prototype.sort. This ensures numbers are ordered numerically rather than lexicographically.
Pass a numeric comparator like a minus b to sort numbers in ascending order.
Is Array.prototype.sort stable across all engines?
Stability is implementation dependent. Some engines preserve relative order for equal elements, while others do not. Don’t rely on stability unless you know the target environment guarantees it.
Stability depends on the engine; don’t rely on it unless your environment guarantees it.
Can you sort arrays of objects by multiple fields?
Yes. Write a comparator that returns a combined order, for example by primary key then a secondary key, as shown in practical examples for Ada and Grace. This ensures deterministic ordering.
Yes, you can sort by more than one field by composing comparator conditions.
Does sort mutate the original array?
Yes. Array.prototype.sort sorts the array in place and returns the same array. If you need to preserve the original, clone it first and then sort the copy.
Sorting changes the original array in place, unless you clone it first.
What about locale aware string sorting?
Use localeCompare within a comparator to respect language rules, including diacritics and case differences. This makes string sorting predictable for users in different locales.
Locale aware sorting uses localeCompare to respect language rules.
What to Remember
- Sort uses an in place API that mutates the original array
- Default sort sorts by string values; numeric sorts require a comparator
- Use localeCompare for locale aware string sorting
- Sort objects by keys with a composed comparator
- Test sorts across engines and environments to avoid surprises