diff --git a/src/components/ChatMessage.tsx b/src/components/ChatMessage.tsx
index b0c0d20..0a19b0a 100644
--- a/src/components/ChatMessage.tsx
+++ b/src/components/ChatMessage.tsx
@@ -5,6 +5,7 @@ import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkBreaks from 'remark-breaks';
import rehypeHighlight from 'rehype-highlight';
+import { rehypeHighlightOptions } from '../lib/highlight';
import type { ChatMessage as ChatMessageType, MessageBlock } from '../types';
import { ThinkingBlock } from './ThinkingBlock';
import { ThinkingIndicator } from './ThinkingIndicator';
@@ -169,7 +170,7 @@ const markdownComponents = { pre: CodeBlock, img: MarkdownImage, a: MarkdownLink
function renderTextBlocks(blocks: MessageBlock[]) {
return getTextBlocks(blocks).map((block, i) => (
-
+
{autoFormatText((block as Extract).text)}
@@ -470,7 +471,7 @@ export function ChatMessageComponent({ message: rawMessage, onRetry, agentAvatar
{/* User-visible text */}
{message.blocks.length > 0 ? renderTextBlocks(message.blocks) : (
-
+
{autoFormatText(message.content)}
diff --git a/src/components/ToolCall.tsx b/src/components/ToolCall.tsx
index eee7a23..7367187 100644
--- a/src/components/ToolCall.tsx
+++ b/src/components/ToolCall.tsx
@@ -1,6 +1,6 @@
import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
import { ChevronRight, ChevronDown, Check, Copy, WrapText, AlignLeft } from 'lucide-react';
-import hljs from 'highlight.js/lib/common';
+import hljs from '../lib/highlight';
import { useT } from '../hooks/useLocale';
import { ImageBlock } from './ImageBlock';
import { useToolCollapse } from '../hooks/useToolCollapse';
diff --git a/src/lib/highlight.ts b/src/lib/highlight.ts
new file mode 100644
index 0000000..5392202
--- /dev/null
+++ b/src/lib/highlight.ts
@@ -0,0 +1,80 @@
+/**
+ * Custom highlight.js bundle with only the languages relevant for
+ * a coding-assistant chat UI. This replaces `highlight.js/lib/common`
+ * (36 languages) with a focused subset (~16), cutting bundle size significantly.
+ */
+import hljs from 'highlight.js/lib/core';
+import type { LanguageFn } from 'highlight.js';
+
+// Languages commonly seen in AI assistant conversations
+import bash from 'highlight.js/lib/languages/bash';
+import css from 'highlight.js/lib/languages/css';
+import diff from 'highlight.js/lib/languages/diff';
+import dockerfile from 'highlight.js/lib/languages/dockerfile';
+import go from 'highlight.js/lib/languages/go';
+import ini from 'highlight.js/lib/languages/ini';
+import javascript from 'highlight.js/lib/languages/javascript';
+import json from 'highlight.js/lib/languages/json';
+import markdown from 'highlight.js/lib/languages/markdown';
+import python from 'highlight.js/lib/languages/python';
+import rust from 'highlight.js/lib/languages/rust';
+import shell from 'highlight.js/lib/languages/shell';
+import sql from 'highlight.js/lib/languages/sql';
+import typescript from 'highlight.js/lib/languages/typescript';
+import xml from 'highlight.js/lib/languages/xml';
+import yaml from 'highlight.js/lib/languages/yaml';
+
+hljs.registerLanguage('bash', bash);
+hljs.registerLanguage('css', css);
+hljs.registerLanguage('diff', diff);
+hljs.registerLanguage('dockerfile', dockerfile);
+hljs.registerLanguage('go', go);
+hljs.registerLanguage('ini', ini);
+hljs.registerLanguage('javascript', javascript);
+hljs.registerLanguage('json', json);
+hljs.registerLanguage('markdown', markdown);
+hljs.registerLanguage('python', python);
+hljs.registerLanguage('rust', rust);
+hljs.registerLanguage('shell', shell);
+hljs.registerLanguage('sql', sql);
+hljs.registerLanguage('typescript', typescript);
+hljs.registerLanguage('xml', xml);
+hljs.registerLanguage('yaml', yaml);
+
+// Aliases for hljs direct usage (ToolCall.tsx)
+hljs.registerAliases(['sh', 'zsh'], { languageName: 'bash' });
+hljs.registerAliases(['js', 'jsx'], { languageName: 'javascript' });
+hljs.registerAliases(['ts', 'tsx'], { languageName: 'typescript' });
+hljs.registerAliases(['py'], { languageName: 'python' });
+hljs.registerAliases(['html'], { languageName: 'xml' });
+hljs.registerAliases(['yml'], { languageName: 'yaml' });
+hljs.registerAliases(['toml', 'cfg', 'conf'], { languageName: 'ini' });
+hljs.registerAliases(['rs'], { languageName: 'rust' });
+
+/**
+ * Language map for rehype-highlight (used in ChatMessage.tsx).
+ * rehype-highlight uses lowlight internally and accepts a `languages` record.
+ */
+export const rehypeHighlightLanguages: Record = {
+ bash, css, diff, dockerfile, go, ini, javascript, json,
+ markdown, python, rust, shell, sql, typescript, xml, yaml,
+};
+
+/**
+ * rehype-highlight options with our custom language subset.
+ */
+export const rehypeHighlightOptions = {
+ languages: rehypeHighlightLanguages,
+ aliases: {
+ bash: ['sh', 'zsh'],
+ javascript: ['js', 'jsx'],
+ typescript: ['ts', 'tsx'],
+ python: ['py'],
+ xml: ['html'],
+ yaml: ['yml'],
+ ini: ['toml', 'cfg', 'conf'],
+ rust: ['rs'],
+ },
+} as const;
+
+export default hljs;