Skip to main content

Cloudsoft Zone Build, deploy and scale with practical guides to PHP, Node.js, React, DevOps and AI automation. Explore the guides

Cloudsoft Zone
JavaScriptInterview questionsTutorial

Bubble sort in JavaScript: how it works, code and complexity

How bubble sort works step by step, a tested JavaScript implementation with early exit and a comparator, its time complexity, and how it compares with the built-in sort.

Cloudsoft Zone

Updated 5 min read

A cluster of soap bubbles of different sizes against a black background, with the Cloudsoft Zone logo in the corner
In this article

Bubble sort repeatedly walks through an array, compares each pair of neighbours and swaps them when they are in the wrong order. After each pass the largest remaining value has "bubbled" to the end, so the next pass can stop one place earlier. It takes O(n²) time, which makes it too slow for real data, but it is the usual first sorting algorithm in courses and interviews because it is short, easy to trace by hand and shows the ideas of passes, swaps, stability and early exit.

Tested with Node.js 24.19.0 (V8 13.6). Every result shown in a comment was printed by running the code. The implementation was checked against toSorted() on 2,000 random arrays.

How bubble sort works, pass by pass

Take [5, 1, 4, 2, 8]. In the first pass 5 is compared with 1 and swapped, then with 4 and swapped, then with 2 and swapped, and finally with 8, which is larger, so it stays. Printing the array after each pass of the implementation below:

Text
pass 1: 1 4 2 5 8 | next end 2
pass 2: 1 2 4 5 8 | next end 1
pass 3: 1 2 4 5 8 | next end 0

"Next end" is the position of the last swap in that pass. Everything after it is already in its final place, so the next pass only has to go that far. When a pass makes no swaps, the array is sorted and the loop stops.

The textbook version

JavaScript
// The textbook version: n - 1 passes, each one bubbling the largest remaining value to the end.
function bubbleSortBasic(input) {
  const items = [...input];
  for (let pass = 0; pass < items.length - 1; pass++) {
    for (let i = 0; i < items.length - 1 - pass; i++) {
      if (items[i] > items[i + 1]) [items[i], items[i + 1]] = [items[i + 1], items[i]];
    }
  }
  return items;
}
console.log(bubbleSortBasic([5, 1, 4, 2, 8])); // [ 1, 2, 4, 5, 8 ]

This always makes n − 1 passes, even when the array is already sorted. It is the version most courses show first.

An optimised, reusable version

This version remembers where the last swap happened, stops as soon as a pass makes no swaps, sorts a copy instead of changing the input, and accepts a comparator with the same contract as Array.prototype.sort:

JavaScript
// Sorts a copy in ascending order; compare works like Array.prototype.sort's comparator.
export function bubbleSort(input, compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0)) {
  const items = [...input];
  let end = items.length - 1;
  while (end > 0) {
    let lastSwap = 0;
    for (let i = 0; i < end; i++) {
      if (compare(items[i], items[i + 1]) > 0) {
        [items[i], items[i + 1]] = [items[i + 1], items[i]];
        lastSwap = i;
      }
    }
    end = lastSwap; // everything after the last swap is already in place; 0 means no swaps, so stop
  }
  return items;
}
JavaScript
bubbleSort([10, 9, 1]);                                   // [ 1, 9, 10 ]
bubbleSort(['pear', 'Apple', 'fig'], (a, b) => a.localeCompare(b)); // [ 'Apple', 'fig', 'pear' ]

const people = [
  { name: 'Ravi', age: 30 }, { name: 'Ana', age: 25 },
  { name: 'Lee', age: 30 }, { name: 'Bo', age: 25 },
];
bubbleSort(people, (a, b) => a.age - b.age).map((p) => p.name);
// [ 'Ana', 'Bo', 'Ravi', 'Lee' ]  (equal ages keep their original order: the sort is stable)

The default comparator uses < and >, so numbers sort numerically. That differs from the built-in sort(), which without a comparator converts values to strings and puts 10 before 9.

Time and space complexity

CaseComparisonsExample (6 items)
Best: already sortedO(n), one pass with early exit5 comparisons
AverageO(n²)–
Worst: reverse orderO(n²), n(n − 1)/215 comparisons

We counted the comparisons in the table by running the function. Extra space is O(1) when sorting in place; our version uses O(n) because it copies the input first, which you can remove if changing the array is acceptable. Bubble sort is stable, because it only swaps neighbours that are strictly out of order, so equal items never pass each other.

Bubble sort versus the built-in sort

Sorting random numbers with our function and with toSorted() on Node.js 24.19.0:

ItemsBubble sorttoSorted((a, b) => a - b)
1,0009 ms0.6 ms
10,000612 ms2.3 ms

Ten times more data took about 67 times longer with bubble sort, which is what O(n²) means in practice. V8's built-in sort uses TimSort, which is O(n log n) and also stable. In real code, use array.toSorted(compare) to get a sorted copy or array.sort(compare) to sort in place. Bubble sort only makes sense for teaching, for tiny arrays that are almost sorted, or on hardware where code size matters more than speed.

Bubble sort interview questions

  • Why can each pass stop one place earlier? Each pass moves the largest remaining value to its final position at the end.
  • How do you make it O(n) on sorted input? Track whether a pass swapped anything and stop when it did not.
  • Is it stable? Yes, as long as you swap only when the left item is strictly greater.
  • How does it compare with insertion sort? Both are O(n²) and stable, but insertion sort usually makes fewer writes and is faster on nearly sorted data, which is why real sort implementations such as TimSort use insertion sort for short runs.

For more questions on arrays, closures and asynchronous code, see our JavaScript interview questions and answers.

Frequently asked questions

  • What is the time complexity of bubble sort?

    O(n²) in the average and worst cases. With an early exit when a pass makes no swaps, the best case, an already sorted array, is O(n). It needs O(1) extra space when it sorts in place.

  • Is bubble sort stable?

    Yes. It only swaps neighbours when the left one is strictly greater, so equal items keep their original order.

  • Should I use bubble sort in JavaScript?

    Not in production code. array.toSorted(compare) or array.sort(compare) is O(n log n), stable and far faster. Bubble sort is useful for learning and interviews.

  • Why does [10, 9, 1].sort() return [1, 10, 9]?

    Without a comparator, sort() compares values as strings, and the string "10" comes before "9". Pass (a, b) => a - b to sort numbers.

Advertise on CloudSoftZone

Your next customer could start right here.

Introduce your tool, product or business to readers exploring technology.

Advertise with us

Explore placements and request a private quote

Sources

  1. Array.prototype.sort() — MDN Web Docs
  2. Array.prototype.toSorted() — MDN Web Docs
  3. Getting things sorted in V8 — V8, 2018-09-28
  4. Bubble sort — Wikipedia

Written with substantial AI assistance. Facts checked against cited sources. Editorial policy.

Comments

No comments yet. Be the first to join the conversation.

Leave a comment

Every comment is read by a moderator before it appears. Your email address is never published; it is used only to contact you about this comment.

Never published. Used only to contact you about this comment.

Loading the security check…

Comments are moderated before publication.