diff --git a/src/utils.ts b/src/utils.ts
index d64c896..a91757e 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -3,61 +3,67 @@ import type { DeepMerge, SimplifyDeep } from './types'
 /**
  * Deep Merge
  *
- * Merges arrays if both configs are arrays, otherwise does object deep merge.
+ * Merges two objects or arrays deeply.
  *
- * @param target - The target object.
- * @param sources - The source objects.
+ * @param target - The target object (default config).
+ * @param source - The source objects (loaded configs that should override defaults).
  * @returns The merged object.
- * @example ```ts
- * deepMerge({ foo: 'bar' }, { bar: 'baz' })
- * deepMerge([{ foo: 'bar' }], [{ bar: 'baz' }])
- * deepMerge({ foo: 'bar' }, [{ foo: 'baz' }])
- * ```
  */
-export function deepMerge<T, S>(target: T, ...sources: S[]): T extends object
+export function deepMerge<T, S>(target: T, source: S): T extends any[]
   ? S extends any[]
-    ? S
-    : S extends object
-      ? SimplifyDeep<DeepMerge<T, S>>
-      : T
-  : T extends any[]
+    ? Array<SimplifyDeep<DeepMerge<T[number], S[number]>>>
+    : S
+  : T extends object
     ? S extends any[]
-      ? T
-      : T
+      ? S
+      : S extends object
+        ? SimplifyDeep<DeepMerge<T, S>>
+        : T
     : T {
-  if (!sources.length)
-    return target as any
+  // If source is an array and target isn't, return source
+  if (Array.isArray(source) && !Array.isArray(target)) {
+    return source as any
+  }
 
-  const source = sources.shift()
-  if (!source)
-    return target as any
+  // If both are arrays, merge their contents
+  if (Array.isArray(source) && Array.isArray(target)) {
+    return source.map((sourceItem, index) => {
+      const targetItem = target[index]
+      if (isObject(sourceItem) && isObject(targetItem)) {
+        return deepMerge(targetItem, sourceItem)
+      }
+      return sourceItem
+    }) as any
+  }
 
-  if (Array.isArray(source) !== Array.isArray(target)
-    || isObject(source) !== isObject(target)) {
+  // Handle non-objects (primitives)
+  if (!isObject(source) || !isObject(target)) {
     return source as any
   }
 
-  if (Array.isArray(target) && Array.isArray(source)) {
-    return [...target, ...source] as any
-  }
+  // Handle objects
+  const merged = { ...target } as any
 
-  if (isObject(target) && isObject(source)) {
-    for (const key in source) {
-      if (Object.prototype.hasOwnProperty.call(source, key)) {
-        const sourceValue = source[key]
-        if (!Object.prototype.hasOwnProperty.call(target, key)) {
-          (target as any)[key] = sourceValue
-          continue
-        }
+  for (const key in source) {
+    if (Object.prototype.hasOwnProperty.call(source, key)) {
+      const sourceValue = source[key]
+      const targetValue = merged[key]
 
-        (target as any)[key] = deepMerge((target as any)[key], sourceValue)
+      if (sourceValue === null || sourceValue === undefined) {
+        merged[key] = sourceValue
+      }
+      else if (isObject(sourceValue) && isObject(targetValue)) {
+        merged[key] = deepMerge(targetValue, sourceValue)
+      }
+      else {
+        merged[key] = sourceValue
       }
     }
   }
 
-  return deepMerge(target, ...sources)
+  return merged
 }
 
 function isObject(item: unknown): item is Record<string, unknown> {
-  return (item && typeof item === 'object' && !Array.isArray(item)) as boolean
+  return Boolean(item && typeof item === 'object' && !Array.isArray(item))
 }