← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

toSorted / toReversed / with — Immutable Array Methods

JavaScript ES2023 Beginner
debt(d7/e3/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). No detection tools are listed in detection_hints.tools. The bug caused by using sort()/reverse() instead of toSorted()/toReversed() on shared state is silent at parse and lint time — it manifests only when the mutated array produces unexpected UI or logic behaviour at runtime, requiring careful code review or testing to catch. Standard linters do not flag mutable sort on shared arrays by default.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes a direct method-name swap: arr.sort(fn) → arr.toSorted(fn), arr.reverse() → arr.toReversed(), and spread patterns → arr.with(i, v). This is slightly more than a trivial one-liner because you must audit all call sites where shared arrays are sorted/reversed, but each individual fix is a small, localised pattern replacement within one component.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The applies_to covers web and cli broadly, but the actual burden is localised: only the places in the codebase that sort or reverse shared arrays are affected. It does not impose a cross-cutting architectural cost; once you adopt toSorted/toReversed at a given call site, the rest of the codebase is unaffected. The main ongoing tax is compatibility checking (ES2023/Node 20+) for teams supporting older environments.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field highlights two documented gotchas: (1) developers assume toSorted() is meaningfully slower than sort(), which is false, causing unnecessary avoidance; and (2) with() looks like a setter but returns a new array rather than mutating in place — arr.with(2, 99) vs arr[2] = 99 is a documented source of confusion that most developers learn after encountering it. These are notable but well-documented surprises rather than catastrophic or deeply contradictory behaviours.

About DEBT scoring →

Also Known As

toSorted toReversed Array.with immutable array methods ES2023 arrays

TL;DR

JavaScript ES2023 adds immutable counterparts to mutating array methods: toSorted() returns a sorted copy, toReversed() returns a reversed copy, and with(index, value) returns a copy with one element replaced — none mutate the original array.

Explanation

JavaScript's sort(), reverse(), and direct index assignment mutate arrays in place — a common source of bugs when arrays are shared across components or passed to functions. ES2023 standardises immutable alternatives: Array.prototype.toSorted() returns a new sorted array without touching the original. Array.prototype.toReversed() returns a new reversed array. Array.prototype.with(index, value) returns a copy with the element at index replaced with value — equivalent to the spread pattern '[...arr.slice(0, i), value, ...arr.slice(i+1)]' but readable. Array.prototype.toSpliced() is the immutable splice(). These also work on TypedArrays.

Common Misconception

toSorted() is slower because it copies the array. The copy overhead is O(n) — the same cost you pay manually with [...arr].sort(). The clarity and safety benefit is free.

Why It Matters

Accidental mutation of a shared array is one of the most common JS bugs — sort() on a React state array mutates it before the re-render, causing unpredictable behaviour. toSorted() makes immutability the default for these operations. The with() method is particularly valuable in state management: updating one item in an array without spread syntax.

Common Mistakes

  • Using toSorted() in environments that don't support ES2023 — check browser compatibility or add a polyfill; Node.js 20+ supports all four methods.
  • Confusing with() with a setter — arr.with(2, 99) returns a new array; arr[2] = 99 mutates in place. They are not interchangeable.
  • Not using toSorted() in React or similar frameworks where prop mutation causes silent bugs — this is the primary use case for these methods.
  • Forgetting toSpliced() — toSorted, toReversed, and with() are well-known, but toSpliced() (immutable splice) is less remembered and equally useful.

Code Examples

✗ Vulnerable
// ❌ sort() mutates the original — React state bug
function ProductList({ products }) {
    const sorted = products.sort((a, b) => a.price - b.price);
    // products (the prop) is now mutated!
    // Parent component's state changed without a setState call
    return sorted.map(p => <Product key={p.id} {...p} />);
}

// ❌ Verbose immutable update
const updated = [
    ...items.slice(0, index),
    newItem,
    ...items.slice(index + 1),
];
✓ Fixed
// ✅ toSorted() — original unchanged
function ProductList({ products }) {
    const sorted = products.toSorted((a, b) => a.price - b.price);
    // products is untouched
    return sorted.map(p => <Product key={p.id} {...p} />);
}

// ✅ with() — readable single-item update
const updated = items.with(index, newItem);

// ✅ Full set of ES2023 immutable methods
const arr = [3, 1, 4, 1, 5];
const sorted   = arr.toSorted();          // [1, 1, 3, 4, 5]
const reversed = arr.toReversed();        // [5, 1, 4, 1, 3]
const replaced = arr.with(2, 99);         // [3, 1, 99, 1, 5]
const spliced  = arr.toSpliced(1, 2, 9); // [3, 9, 1, 5]
// arr is still [3, 1, 4, 1, 5] throughout

Added 23 Mar 2026
Edited 5 Apr 2026
Views 113
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 2 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 14 ChatGPT 7 Ahrefs 7 SEMrush 7 PetalBot 7 Scrapy 6 Perplexity 4 Google 3 Claude 2 Bing 2 Twitter/X 2 Brave Search 2 Applebot 2 Majestic 1 Meta AI 1
crawler 63 crawler_json 4
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
JavaScript javascript The programming language of the browser — it reads and modifies the page (the DOM), reacts to user events, and fetches data without reloading.

JavaScript is the only language browsers execute, so every interactive behaviour on the web goes through it. Its two defining traits — single-threaded event loop and loose typing (== coercion) — explain the majority of both its bugs and its design patterns.

💡 Default to const, use === always, and reach for let only when a value genuinely reassigns.

Ask Codex about JavaScript →
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Replace arr.sort(fn) with arr.toSorted(fn) and arr.reverse() with arr.toReversed() when you do not intend to mutate the original. Replace [...arr.slice(0,i), v, ...arr.slice(i+1)] with arr.with(i, v).
📦 Applies To
javascript ES2023 web cli


✓ schema.org compliant