Code Block

Display syntax-highlighted code snippets.
TypeScriptCounter.tsx
<CodeBlock.Root  id="code-block-preview-typescript"  code={`import { useState } from \"react\";export function Counter() {  const [count, setCount] = useState(0);  return (    <button onClick={() => setCount(c => c + 1)}>      Count: {count}    </button>  );}`}  language="typescript"  lineNumbers="visible"  filename="Counter.tsx">  <CodeBlock.Header />  <CodeBlock.Content />  <CodeBlock.CollapseToggle /></CodeBlock.Root>

When the assistant generates or references code, unstyled monospace text sells it short. CodeBlock renders syntax-highlighted snippets with line numbers and a copy button. You can highlight specific lines to draw attention to changes or bugs, and collapse long snippets with maxCollapsedLines to keep conversations scannable.

Role: Information. For displaying data the user reads. See Design Guidelines for how component roles work.

Getting Started

Run this once from your project root.

npx shadcn@latest add @tool-ui/code-block

Render CodeBlock in your UI with tool-compatible props.

import { CodeBlock } from "@/components/tool-ui/code-block";export function MyComponent() {  return (    <CodeBlock      id="my-code-example"      code={`function hello(name: string) {  return \`Hello, \${name}!\`;}`}      language="typescript"      lineNumbers="visible"      filename="hello.ts"    />  );}

Register this renderer so tool results display as CodeBlock.

// Backend toolimport { tool, jsonSchema } from "ai";const showCodeBlock = tool({  description: "Show a code snippet",  inputSchema: jsonSchema<{}>({    type: "object",    properties: {},    additionalProperties: false,  }),  async execute() {    return {      id: "code-block-1",      code: "console.log('hello');",      language: "javascript",      filename: "hello.js",      highlightLines: [1],    };  },});// Frontend with assistant-uiimport { type Toolkit } from "@assistant-ui/react";import { CodeBlock } from "@/components/tool-ui/code-block";import { safeParseSerializableCodeBlock } from "@/components/tool-ui/code-block/schema";import { createResultToolRenderer } from "@/components/tool-ui/shared";export const toolkit: Toolkit = {  showCodeBlock: {    type: "backend",    render: createResultToolRenderer({      safeParse: safeParseSerializableCodeBlock,      render: (parsedResult) => (        <CodeBlock {...parsedResult} />      ),    }),  },};

Key Features

Syntax highlighting

Shiki-powered with 100+ languages

Line highlighting

Draw attention to specific lines for explanations or diffs

Collapsible mode

Opt-in collapse for long snippets via maxCollapsedLines

Filename header

Filename and language badge in the header

Props

Core Props

Prop

Type

Display Options

Prop

Type

Standard Props

Prop

Type

Use ToolUI.LocalActions to compose external actions next to CodeBlock.

Supported Languages

CodeBlock supports all languages included with Shiki, including:

  • TypeScript/JavaScript
  • Python
  • JSON
  • Bash/Shell
  • CSS/HTML
  • Markdown
  • SQL
  • YAML
  • Go
  • Rust
  • And many more...

See Shiki documentation for the complete list.

Accessibility

  • Collapsible sections use Radix Collapsible with proper ARIA attributes
  • Copy button is keyboard-accessible with focus indication
  • Code content is selectable and works with screen readers
  • Terminal: command-line output and logs