diff --git a/sorts/cocktial_sort.ts b/sorts/cocktial_sort.ts
new file mode 100644
index 00000000..bba00bcd
--- /dev/null
+++ b/sorts/cocktial_sort.ts
@@ -0,0 +1,51 @@
+/**
+ * @author codeme254 (Dennis Otwoma)
+ * @description
+ * Cocktail sort is meant to be an improvement of the
+ * bubble sort algorithm, it bubbles bigger elements
+ * to the end of the list and once at the end of the list,
+ * it bubbles smaller elements to the start of the list.
+ * The algorithm keeps swapping elements until all the
+ * elements are where they are supposed to be, if at any
+ * given pass no swapping happens, it means the array is sorted.
+ * @example
+ * const array = [32, 87, 14, 57, 60, 2, 72, 90, 45, 30]
+ * cocktailSort([32, 87, 14, 57, 60, 2, 72, 90, 45, 30])
+ */
+
+export const cocktailSort = (array: number[]): number[] => {
+  if (array.length <= 0) return array
+  let sortedLeft = 0
+  let sortedRight = array.length - 1
+
+  while (sortedLeft <= sortedRight) {
+    let i = sortedLeft
+    let swapHappened = false
+    while (i < sortedRight) {
+      if (array[i] > array[i + 1]) {
+        [array[i], array[i + 1]] = [array[i + 1], array[i]]
+        swapHappened = true
+      }
+      i += 1
+    }
+
+    // if no swap happened in the forward pass, it means the array is sorted
+    if (swapHappened === false) return array
+
+    swapHappened = false
+    while (i > sortedLeft) {
+      if (array[i] < array[i - 1]) {
+        [array[i], array[i - 1]] = [array[i - 1], array[i]]
+        swapHappened = true
+      }
+      i -= 1
+    }
+
+    // if no swap happened in the backwards pass, it means the array is sorted
+    if (swapHappened === false) return array
+
+    sortedLeft += 1
+    sortedRight -= 1
+  }
+  return array
+}
diff --git a/sorts/test/cocktail_sort.test.ts b/sorts/test/cocktail_sort.test.ts
new file mode 100644
index 00000000..858f25f9
--- /dev/null
+++ b/sorts/test/cocktail_sort.test.ts
@@ -0,0 +1,47 @@
+import { cocktailSort } from '../cocktial_sort'
+
+const testCases = [
+  [
+    [5, 2, 9, 1, 3],
+    [1, 2, 3, 5, 9]
+  ],
+  [
+    [9, 8, 5, 1, 0],
+    [0, 1, 5, 8, 9]
+  ],
+  [[], []],
+  [[3], [3]],
+  [
+    [32, 87, 14, 57, 60, 2, 72, 90, 45, 30],
+    [2, 14, 30, 32, 45, 57, 60, 72, 87, 90]
+  ],
+  [
+    [1, 2, 5, 9, 12],
+    [1, 2, 5, 9, 12]
+  ],
+  [
+    [3, 1, 2, 3, 1],
+    [1, 1, 2, 3, 3]
+  ],
+  [
+    [7, 7, 7, 7],
+    [7, 7, 7, 7]
+  ],
+  [
+    [-3, -1, -4, -2, -5],
+    [-5, -4, -3, -2, -1]
+  ],
+  [
+    [-2, 4, -1, 3, 0],
+    [-2, -1, 0, 3, 4]
+  ],
+  [
+    [1, 100, 2, 99, 3, 98],
+    [1, 2, 3, 98, 99, 100]
+  ]
+]
+
+it.each(testCases)('%p sorted is %p', (input, expected) => {
+  const sorted = cocktailSort(input)
+  expect(sorted).toEqual(expected)
+})