toSorted() is the non-mutating counterpart to sort(), part of a 2023 wave of "immutable by default" array methods. It solves sort()'s most common footgun without needing a manual spread-copy first.
1toSorted() | JavaScript Tutorial - In-Depth Guide Part 1
toSorted() sorts an array and returns a new array, leaving the original array completely untouched.
const original = [3, 1, 2];
const sorted = original.toSorted();
original; // [3, 1, 2] โ untouched
sorted; // [1, 2, 3]Sort Without Mutating
2toSorted() | JavaScript Tutorial - In-Depth Guide Part 2
Before toSorted() existed, the standard workaround was spreading the array first: '[...arr].sort()'.
// Old idiom:
const sortedOld = [...original].sort((a, b) => a - b);
// Modern equivalent:
const sortedNew = original.toSorted((a, b) => a - b);Replaces the Spread Idiom
3toSorted() | JavaScript Tutorial - In-Depth Guide Part 3
toSorted() accepts the exact same comparator function signature as sort() โ everything you know about writing comparators transfers directly.
const byAge = users.toSorted((a, b) => a.age - b.age);Same Comparator Rules
4toSorted() | JavaScript Tutorial - In-Depth Guide Part 4
Immutable state-management patterns (like Redux reducers) benefit directly from toSorted(), since mutating state in place is forbidden in those systems.
function reducer(state, action) {
if (action.type === 'SORT_BY_PRICE') {
return { ...state, items: state.items.toSorted((a, b) => a.price - b.price) };
}
return state;
}Fits Immutable State
5toSorted() | JavaScript Tutorial - In-Depth Guide Part 5
toSorted() is one of a family of new non-mutating array methods (alongside toReversed, toSpliced, and with) introduced together to complement their mutating counterparts.
arr.toSorted(); // vs arr.sort()
arr.toReversed(); // vs arr.reverse()
arr.toSpliced(); // vs arr.splice()Part of a New Family
6Step-by-Step Breakdown
toSorted() sorts an array and returns a new array, leaving the original array completely untouched.
Checkpoint: After calling arr.toSorted(), is the original arr mutated?
- โYes, just like sort()
- โNo, the original array is left unchanged
Before toSorted() existed, the standard workaround was spreading the array first: '[...arr].sort()'.
toSorted() accepts the exact same comparator function signature as sort() โ everything you know about writing comparators transfers directly.
Checkpoint: Does toSorted() require a different comparator function signature than sort()?
- โYes, it uses a new comparator API
- โNo, it accepts the exact same comparator function
Immutable state-management patterns (like Redux reducers) benefit directly from toSorted(), since mutating state in place is forbidden in those systems.
toSorted() is one of a family of new non-mutating array methods (alongside toReversed, toSpliced, and with) introduced together to complement their mutating counterparts.
Next, we'll explore 'Immutable Reversing: toReversed()'.
Level Up ๐
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Immutable Sorting Keeps Focus and Live Region Announcements Consistent
When a sortable, accessible data table re-sorts its underlying array with toSorted() instead of mutating it, other parts of the UI relying on the original array reference (like a live region summarizing 'showing N of M items') stay correct instead of silently reflecting the new sort order too.
SEO Implications
- 1
No Direct SEO Effect
toSorted() is a state-management correctness tool; SEO relevance is limited to preventing shared-state bugs in server-rendered listing pages.
Best Practices
Prefer toSorted() Over [...arr].sort() in Modern Codebases
It expresses the same non-mutating intent with less syntax and no risk of forgetting the spread, in any environment targeting reasonably modern JavaScript runtimes.
Use toSorted() by Default Inside Reducers and Other Immutable-State Contexts
It removes the temptation to reach for the mutating sort() inside code where mutation is explicitly forbidden or dangerous.
Frequent Bugs
Using sort() instead of toSorted() inside a reducer or other immutable-state function, silently mutating the state array that other parts of the app still hold a reference to.
Switch to toSorted() (or the older spread-copy idiom in environments without it) anywhere state must not be mutated directly.
Assuming toSorted() needs a different comparator convention than sort(), and writing unnecessary conversion logic.
Reuse the exact same comparator function you would have passed to sort() โ the two methods share an identical comparator contract.
Real-World Examples
Sorting a Leaderboard Without Mutating Shared State
A game's leaderboard component needed to display players sorted by score, without mutating the shared players array used elsewhere in the app for other calculations.
const leaderboard = players.toSorted((a, b) => b.score - a.score);
// `players` remains in its original order for other consumers