diff --git a/README.md b/README.md
index 4f7ddc04..6c687f2d 100644
--- a/README.md
+++ b/README.md
@@ -88,6 +88,7 @@ $rendererOptions = [
     'detailLevel' => 'line',
     // renderer language: eng, cht, chs, jpn, ...
     // or an array which has the same keys with a language file
+    // check the "Custom Language" section in the readme for more advanced usage
     'language' => 'eng',
     // show line numbers in HTML renderers
     'lineNumbers' => true,
@@ -598,6 +599,26 @@ If you don't need those detailed diff, consider using the `JsonText` renderer.
 
 </details>
 
+## Custom Language
+
+### Override an Existing Language
+
+If you just want to override some translations of an existing language...
+
+```php
+$rendererOptions = [
+  'language' => [
+    // use English as the base language
+    'eng',
+    // your custom overrides
+    [
+      // use "Diff" as the new value of the "differences" key
+      'differences' => 'Diff',
+    ],
+    // maybe more overrides if you somehow need them...
+  ],
+]
+```
 
 ## Acknowledgment
 
diff --git a/example/demo_base.php b/example/demo_base.php
index a435d197..a61c1693 100644
--- a/example/demo_base.php
+++ b/example/demo_base.php
@@ -30,6 +30,7 @@
     'detailLevel' => 'line',
     // renderer language: eng, cht, chs, jpn, ...
     // or an array which has the same keys with a language file
+    // check the "Custom Language" section in the readme for more advanced usage
     'language' => 'eng',
     // show line numbers in HTML renderers
     'lineNumbers' => true,
diff --git a/src/Renderer/AbstractRenderer.php b/src/Renderer/AbstractRenderer.php
index d2906091..d9806a34 100644
--- a/src/Renderer/AbstractRenderer.php
+++ b/src/Renderer/AbstractRenderer.php
@@ -59,6 +59,7 @@ abstract class AbstractRenderer implements RendererInterface
         'detailLevel' => 'line',
         // renderer language: eng, cht, chs, jpn, ...
         // or an array which has the same keys with a language file
+        // check the "Custom Language" section in the readme for more advanced usage
         'language' => 'eng',
         // show line numbers in HTML renderers
         'lineNumbers' => true,
diff --git a/src/Utility/Arr.php b/src/Utility/Arr.php
index da3c734e..0ebcb7ef 100644
--- a/src/Utility/Arr.php
+++ b/src/Utility/Arr.php
@@ -44,4 +44,22 @@ public static function getPartialByIndex(array $array, int $start = 0, ?int $end
         // make the length non-negative
         return \array_slice($array, $start, max(0, $end - $start));
     }
+
+    /**
+     * Determines whether the array is associative.
+     *
+     * @param array $arr the array
+     *
+     * @return bool `true` if the array is associative, `false` otherwise
+     */
+    public static function isAssociative($arr): bool
+    {
+        foreach ($arr as $key => $value) {
+            if (\is_string($key)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }
diff --git a/src/Utility/Language.php b/src/Utility/Language.php
index d9640afe..b429c5fa 100644
--- a/src/Utility/Language.php
+++ b/src/Utility/Language.php
@@ -19,55 +19,52 @@ final class Language
     /**
      * The constructor.
      *
-     * @param string|string[] $target the language string or translations dict
+     * @param array<int,string|string[]>|string|string[] $target the language ID or translations dict
      */
     public function __construct($target = 'eng')
     {
-        $this->setLanguageOrTranslations($target);
+        $this->load($target);
     }
 
     /**
-     * Set up this class.
+     * Gets the language.
      *
-     * @param string|string[] $target the language string or translations array
-     *
-     * @throws \InvalidArgumentException
+     * @return string the language
      */
-    public function setLanguageOrTranslations($target): self
+    public function getLanguage(): string
     {
-        if (\is_string($target)) {
-            $this->setUpWithLanguage($target);
-
-            return $this;
-        }
-
-        if (\is_array($target)) {
-            $this->setUpWithTranslations($target);
-
-            return $this;
-        }
+        return $this->language;
+    }
 
-        throw new \InvalidArgumentException('$target must be the type of string|string[]');
+    /**
+     * Gets the translations.
+     *
+     * @return array the translations
+     */
+    public function getTranslations(): array
+    {
+        return $this->translations;
     }
 
     /**
-     * Get the language.
+     * Loads the target language.
      *
-     * @return string the language
+     * @param array<int,string|string[]>|string|string[] $target the language ID or translations dict
      */
-    public function getLanguage(): string
+    public function load($target): void
     {
-        return $this->language;
+        $this->translations = $this->resolve($target);
+        $this->language = \is_string($target) ? $target : '_custom_';
     }
 
     /**
-     * Get the translations.
+     * Translates the text.
      *
-     * @return array the translations
+     * @param string $text the text
      */
-    public function getTranslations(): array
+    public function translate(string $text): string
     {
-        return $this->translations;
+        return $this->translations[$text] ?? "![{$text}]";
     }
 
     /**
@@ -81,7 +78,7 @@ public function getTranslations(): array
      *
      * @return string[]
      */
-    public static function getTranslationsByLanguage(string $language): array
+    private static function getTranslationsByLanguage(string $language): array
     {
         $filePath = __DIR__ . "/../languages/{$language}.json";
         $file = new \SplFileObject($filePath, 'r');
@@ -97,39 +94,34 @@ public static function getTranslationsByLanguage(string $language): array
     }
 
     /**
-     * Translation the text.
+     * Resolves the target language.
      *
-     * @param string $text the text
-     */
-    public function translate(string $text): string
-    {
-        return $this->translations[$text] ?? "![{$text}]";
-    }
-
-    /**
-     * Set up this class by language name.
+     * @param array<int,string|string[]>|string|string[] $target the language ID or translations array
      *
-     * @param string $language the language name
-     */
-    private function setUpWithLanguage(string $language): self
-    {
-        return $this->setUpWithTranslations(
-            self::getTranslationsByLanguage($language),
-            $language,
-        );
-    }
-
-    /**
-     * Set up this class by translations.
+     * @throws \InvalidArgumentException
      *
-     * @param string[] $translations the translations dict
-     * @param string   $language     the language name
+     * @return string[] the resolved translations
      */
-    private function setUpWithTranslations(array $translations, string $language = '_custom_'): self
+    private function resolve($target): array
     {
-        $this->language = $language;
-        $this->translations = array_map('strval', $translations);
+        if (\is_string($target)) {
+            return self::getTranslationsByLanguage($target);
+        }
+
+        if (\is_array($target)) {
+            // $target is an associative array
+            if (Arr::isAssociative($target)) {
+                return $target;
+            }
+
+            // $target is a list of "key-value pairs or language ID"
+            return array_reduce(
+                $target,
+                fn ($carry, $translation) => array_merge($carry, $this->resolve($translation)),
+                [],
+            );
+        }
 
-        return $this;
+        throw new \InvalidArgumentException('$target is not in valid form');
     }
 }
diff --git a/tests/Utility/LanguageTest.php b/tests/Utility/LanguageTest.php
index 1c9e7043..472be43a 100644
--- a/tests/Utility/LanguageTest.php
+++ b/tests/Utility/LanguageTest.php
@@ -24,46 +24,34 @@ final class LanguageTest extends TestCase
      */
     protected function setUp(): void
     {
-        $this->languageObj = new Language('eng');
+        $this->languageObj = new Language();
     }
 
     /**
-     * Test the Language::setLanguageOrTranslations.
+     * Test the Language::load.
      *
-     * @covers \Jfcherng\Diff\Utility\Language::setLanguageOrTranslations
+     * @covers \Jfcherng\Diff\Utility\Language::load
      */
-    public function testSetLanguageOrTranslations(): void
+    public function testLoad(): void
     {
-        $this->languageObj->setLanguageOrTranslations('eng');
-        static::assertArrayHasKey(
-            'differences',
-            $this->languageObj->getTranslations(),
-        );
+        $this->languageObj->load('eng');
+        static::assertArrayHasKey('differences', $this->languageObj->getTranslations());
 
-        $this->languageObj->setLanguageOrTranslations(['hahaha' => '哈哈哈']);
-        static::assertArrayHasKey(
-            'hahaha',
-            $this->languageObj->getTranslations(),
-        );
+        $this->languageObj->load(['hahaha' => '哈哈哈']);
+        static::assertArrayHasKey('hahaha', $this->languageObj->getTranslations());
 
-        $this->expectException(\InvalidArgumentException::class);
-        $this->languageObj->setLanguageOrTranslations(5);
-    }
+        $this->languageObj->load([
+            'eng',
+            ['hahaha_1' => '哈哈哈_1', 'hahaha_2' => '哈哈哈_2'],
+            ['hahaha_1' => '哈哈哈_999'],
+        ]);
+        $translations = $this->languageObj->getTranslations();
+        static::assertSame('Differences', $translations['differences']);
+        static::assertSame('哈哈哈_999', $translations['hahaha_1']);
+        static::assertSame('哈哈哈_2', $translations['hahaha_2']);
 
-    /**
-     * Test the Language::getTranslationsByLanguage.
-     *
-     * @covers \Jfcherng\Diff\Utility\Language::getTranslationsByLanguage
-     */
-    public function testGetTranslationsByLanguage(): void
-    {
-        static::assertArrayHasKey(
-            'differences',
-            $this->languageObj->getTranslationsByLanguage('eng'),
-        );
-
-        $this->expectException(\RuntimeException::class);
-        $this->languageObj->getTranslationsByLanguage('a_non_existing_language');
+        $this->expectException(\InvalidArgumentException::class);
+        $this->languageObj->load(5);
     }
 
     /**
@@ -80,7 +68,7 @@ public function testTranslate(): void
 
         static::assertStringMatchesFormat(
             '![%s]',
-            $this->languageObj->translate('a_non_existing_translation'),
+            $this->languageObj->translate('a_non_existing_key'),
         );
     }
 }