Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by itsarghyadas
Edit on GitHub

Code Comparison

A component which compares two code snippets.

Powered by

Installation

bash
npx shadcn@latest add @redpanda/code-comparison
bash
pnpm dlx shadcn@latest add @redpanda/code-comparison
bash
yarn dlx shadcn@latest add @redpanda/code-comparison
bash
bunx shadcn@latest add @redpanda/code-comparison
bash
nubx shadcn@latest add @redpanda/code-comparison
bash
aube dlx shadcn@latest add @redpanda/code-comparison

Usage

The Code Comparison component provides a side-by-side view of code changes with syntax highlighting, diff notation, and focus effects:

tsx
import { CodeComparison } from '@/components/redpanda-ui/code-comparison';
// Basic comparisonconst beforeCode = `function greetUser(name) {  console.log("Hello " + name);}`;
const afterCode = `function greetUser(name: string): void {  console.log(\`Hello \${name}!\`);}`;
export function Example() {  return (    <CodeComparison      beforeCode={beforeCode}      afterCode={afterCode}      language="typescript"      filename="greet.ts"      lightTheme="github-light-high-contrast"      darkTheme="github-dark"    />  );}
// With diff notation and focusconst beforeWithDiff = `function calculateTotal(items) {  let total = 0;  for (let i = 0; i < items.length; i++) { // [!code --]    total += items[i].price;  }  return total;}`;
const afterWithDiff = `function calculateTotal(items: Item[]): number {  let total = 0;  for (const item of items) { // [!code ++]    total += item.price;  }  return total;}`;
export function DiffExample() {  return (    <CodeComparison      beforeCode={beforeWithDiff}      afterCode={afterWithDiff}      language="typescript"      filename="calculate.ts"      lightTheme="catppuccin-latte"      darkTheme="catppuccin-mocha"      highlightColor="var(--color-accent)"    />  );}
// With focus highlightingconst beforeFocus = `function processData(data) {  const result = [];  for (let item of data) {    if (item.active) { // [!code focus]      result.push(transform(item)); // [!code focus]    }  }  return result;}`;
const afterFocus = `function processData(data: DataItem[]): ProcessedItem[] {  const result: ProcessedItem[] = [];  for (const item of data) {    if (item.active) { // [!code focus]      result.push(transform(item)); // [!code focus]    }  }  return result;}`;
export function FocusExample() {  return (    <CodeComparison      beforeCode={beforeFocus}      afterCode={afterFocus}      language="typescript"      filename="process.ts"      lightTheme="material-theme-lighter"      darkTheme="material-theme-darker"    />  );}

If you want to toggle between light and dark themes, you can use the theme prop.

tsx
<CodeComparison  beforeCode={beforeCode}  afterCode={afterCode}  language="typescript"  filename="greet.ts"  lightTheme="github-light-high-contrast"  darkTheme="github-dark"  theme="dark"/>

When to use

Use this decision tree to determine when to use the Code Comparison component:

Use Cases

  • Code refactoring: Show improvements, optimizations, or modernization changes
  • Tutorial content: Step-by-step code evolution in learning materials
  • Code reviews: Visual diff for pull requests or code discussions
  • Bug fixes: Demonstrate problem code vs. solution
  • Migration guides: Show old vs. new API usage patterns
  • Documentation: Compare different approaches or versions

Code Comparison vs Other Components

  • Use Code Comparison when: You need to show side-by-side code changes with visual diff highlighting
  • Use regular CodeBlock when: Displaying single code examples without comparison needs
  • Use diff utilities when: You need inline diff view or text-based comparison
  • Use Tabs when: Switching between entirely different code examples, not comparing changes

Anatomy

The panels stack on small screens and sit side by side from the medium breakpoint. Each panel has a filename header and its own scrollable code surface. The central comparison marker is hidden on small screens.

Shiki loads when highlighting starts. Its notation transformers mark added, removed, highlighted, and focused lines before sanitized HTML is rendered. Focus annotations outline the relevant lines; surrounding code stays fully readable without hover, blur, or reduced opacity. The default highlight surface uses the theme’s accent token.

The light example uses GitHub Light High Contrast. The dark example uses GitHub Dark Default. Both palettes are emitted together unless theme explicitly selects one; the surrounding application theme controls which token colors are painted. Custom palettes and highlight colors remain your responsibility to check against the actual background, including diff and highlight washes.

Props

Credits

  • We take our inspiration from Magic UI for the code comparison component and style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?