diff --git a/Dynamic-Programming/spiralMatrix.js b/Dynamic-Programming/spiralMatrix.js
new file mode 100644
index 0000000000..8ea3a7946d
--- /dev/null
+++ b/Dynamic-Programming/spiralMatrix.js
@@ -0,0 +1,50 @@
+/**
+ * @description Return spiral matrix.
+ * @param {Number} total number of row and column.
+ * @returns {Array [Number][]}
+ */
+function spiralMatrix(N) {
+    const result = []
+  
+    for (let i = 0; i < N; i++) {
+      result.push(new Array(N).fill(null))
+    }
+  
+    let top = 0,
+      level = 0
+    let count = 1
+  
+    while (true) {
+      result[level][top] = count
+  
+      const upLevel = result[level - 1],
+        bottomLevel = result[level + 1],
+        leftLevel = result[level],
+        rightLevel = result[level]
+  
+      const up = upLevel ? upLevel[top] : undefined
+      const bottom = bottomLevel ? bottomLevel[top] : undefined
+      const left = leftLevel ? leftLevel[top - 1] : undefined
+      const right = rightLevel ? rightLevel[top + 1] : undefined
+  
+      if (right === null && up !== null) {
+        top++
+      } else if (right === null && up === null) {
+        level--
+      } else if (right !== null && bottom === null) {
+        level++
+      } else if (right !== null && bottom !== null && left === null) {
+        top--
+      } else if (right !== null && bottom !== null && up === null) {
+        level--
+      } else {
+        break
+      }
+  
+      count++
+    }
+  
+    return result
+}
+  
+module.exports = spiralMatrix;
diff --git a/Dynamic-Programming/tests/spiralMatrix.test.js b/Dynamic-Programming/tests/spiralMatrix.test.js
new file mode 100644
index 0000000000..0bfe7c71ac
--- /dev/null
+++ b/Dynamic-Programming/tests/spiralMatrix.test.js
@@ -0,0 +1,21 @@
+import { expect } from 'vitest'
+import spiralMatrix from '../spiralMatrix'
+
+describe('spiralMatrix', () => {
+  test('should return spiral matrix', () => {
+    const result = spiralMatrix(3)
+    const expected = [
+      [1, 2, 3],
+      [8, 9, 4],
+      [7, 6, 5]
+    ]
+
+    expect(result.length).toBe(expected.length)
+
+    for (let i = 0; i < expected.length; i++) {
+      for (let j = 0; j < expected[i].length; j++) {
+        expect(result[i][j]).toBe(expected[i][j])
+      }
+    }
+  })
+});