diff --git a/22_mergeSort/README.md b/22_mergeSort/README.md
new file mode 100644
index 00000000000..52d618e0697
--- /dev/null
+++ b/22_mergeSort/README.md
@@ -0,0 +1,22 @@
+# Exercise 22 - mergeSort
+
+A significant amount of computer science is dedicated to sorting data. An algorithm which uses the "divide and conquer" approach
+of recursion is able to reduce a sorting problem to smaller and smaller sub-problems.
+
+Merge sort is one such sorting algorithm, and can be much faster than other algorithms such as bubble sort on the right data sets.
+
+Essentially, merge sort recurses through an array of unsorted data until it reaches its smallest sub-set, a single item.
+
+Of course an array with a single item is considered sorted. Merge sort then merges the single items back together in sorted order. Pretty clever!
+
+To understand what merge sort algorithm is doing check out these resources:
+- [Watch this introductory video from Harvard's CS50x course](https://www.youtube.com/watch?v=Ns7tGNbtvV4)
+- [Watch this more detailed video explanation by David J. Malan (watch only until 1:58:33)](https://youtu.be/4oqjcKenCH8?t=6248)
+- [The concept of merging and Merge Sort - How it Works part on YouTube to give you a more formal look at this problem if you're still unclear](https://youtu.be/mB5HXBb_HY8)
+- [Play with this Merge Sort Visualizer to get a better feel for exactly what is happening during a Merge Sort.](https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/visualize/)
+
+Write a function `mergeSort` that takes in an array and returns a sorted array, using a recursive merge sort methodology. Example:
+
+```javascript
+mergeSort([3, 2, 1, 13, 8, 5, 0, 1]) // [0, 1, 1, 2, 3, 5, 8, 13]
+```
diff --git a/22_mergeSort/mergeSort.js b/22_mergeSort/mergeSort.js
new file mode 100644
index 00000000000..d64e7a79205
--- /dev/null
+++ b/22_mergeSort/mergeSort.js
@@ -0,0 +1,6 @@
+const mergeSort = function() {
+  
+};
+  
+// Do not edit below this line
+module.exports = mergeSort;
diff --git a/22_mergeSort/mergeSort.spec.js b/22_mergeSort/mergeSort.spec.js
new file mode 100644
index 00000000000..67a35b5bdf3
--- /dev/null
+++ b/22_mergeSort/mergeSort.spec.js
@@ -0,0 +1,15 @@
+const mergeSort = require('./mergeSort');
+
+describe('mergeSort', () => {
+  test('First test description', () => {
+    // Replace this comment with any other necessary code, and update the expect line as necessary
+
+    expect(mergeSort()).toBe('');
+  });
+  
+  test.skip('Second test description', () => {
+    // Replace this comment with any other necessary code, and update the expect line as necessary
+
+    expect(mergeSort()).toBe('');
+  });
+});
diff --git a/22_mergeSort/solution/mergeSort-solution.js b/22_mergeSort/solution/mergeSort-solution.js
new file mode 100644
index 00000000000..9195378371b
--- /dev/null
+++ b/22_mergeSort/solution/mergeSort-solution.js
@@ -0,0 +1,27 @@
+function mergeSort(array) {
+  if (array.length <= 1) return array;
+
+  const midpoint = Math.floor(array.length / 2);
+  const leftHalf = array.slice(0, midpoint);
+  const rightHalf = array.slice(midpoint);
+
+  return merge(mergeSort(leftHalf), mergeSort(rightHalf));
+}
+
+function merge(left, right, merged = [], leftIndex = 0, rightIndex = 0) {
+  if (leftIndex >= left.length && rightIndex >= right.length) return merged;
+
+  if (
+    leftIndex < left.length &&
+    (rightIndex >= right.length || left[leftIndex] < right[rightIndex])
+  ) {
+    merged.push(left[leftIndex]);
+    return merge(left, right, merged, leftIndex + 1, rightIndex);
+  } else {
+    merged.push(right[rightIndex]);
+    return merge(left, right, merged, leftIndex, rightIndex + 1);
+  }
+}
+
+// Do not edit below this line
+module.exports = mergeSort;
diff --git a/22_mergeSort/solution/mergeSort-solution.spec.js b/22_mergeSort/solution/mergeSort-solution.spec.js
new file mode 100644
index 00000000000..56fecc7b827
--- /dev/null
+++ b/22_mergeSort/solution/mergeSort-solution.spec.js
@@ -0,0 +1,45 @@
+const mergeSort = require('./mergeSort-solution');
+
+describe('mergeSort', () => {
+  test('sorts an array of numbers', () => {
+    expect(mergeSort([4, 1, 3, 9, 7])).toEqual([1, 3, 4, 7, 9]);
+  });
+
+  test('returns an empty array when called with an empty array', () => {
+    expect(mergeSort([])).toEqual([]);
+  });
+
+  test('sorts an array with duplicate elements', () => {
+    expect(mergeSort([5, 3, 8, 3, 2])).toEqual([2, 3, 3, 5, 8]);
+  });
+
+  test('sorts an array of negative numbers', () => {
+    expect(mergeSort([-3, -1, -7, -4])).toEqual([-7, -4, -3, -1]);
+  });
+
+  test('sorts an array with negative and positive numbers', () => {
+    expect(mergeSort([-1, 2, -3, 4, -5])).toEqual([-5, -3, -1, 2, 4]);
+  });
+
+  test('sorts an array with one element', () => {
+    expect(mergeSort([10])).toEqual([10]);
+  });
+
+  test('sorts an already sorted array', () => {
+    expect(mergeSort([1, 2, 3, 4, 5])).toEqual([1, 2, 3, 4, 5]);
+  });
+
+  test('sorts an array in descending order', () => {
+    expect(mergeSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5]);
+  });
+
+  test('sorts a large array', () => {
+    const largeArray = Array.from({ length: 1000 }, () => Math.floor(Math.random() * 1000));
+    const sortedArray = [...largeArray].sort((a, b) => a - b);
+    expect(mergeSort(largeArray)).toEqual(sortedArray);
+  });
+
+  test('handles array with all the same elements', () => {
+    expect(mergeSort([7, 7, 7, 7, 7])).toEqual([7, 7, 7, 7, 7]);
+  });
+});