Redpanda UI
RC
Redpanda UI

Code Comparison

A component which compares two code snippets.

Made by itsarghyadas

Powered by

Loading component...

Installation

Usage

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

import { CodeComparison } from "@/components/redpanda-ui/code-comparison";

// Basic comparison
const 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"
      darkTheme="github-dark"
    />
  );
}

// With diff notation and focus
const 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="#ff6b6b"
    />
  );
}

// With focus highlighting
const 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.

<CodeComparison
  beforeCode={beforeCode}
  afterCode={afterCode}
  language="typescript"
  filename="greet.ts"
  lightTheme="github-light"
  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 Code Comparison component uses Shiki transformers to provide rich diff visualization:

Code Comparison Component Structure:
┌─────────────────────────────────────────────────────────┐
│ Container (max-w-5xl, responsive grid)                 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Border Container (rounded, border)                  │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Grid Layout (md:grid-cols-2)                    │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────────────┐ │ │ │
│ │ │ │ Left Panel      │ │ Right Panel             │ │ │ │
│ │ │ │ (Before Code)   │ │ (After Code)            │ │ │ │
│ │ │ │ ┌─────────────┐ │ │ ┌─────────────────────┐ │ │ │ │
│ │ │ │ │ Header      │ │ │ │ Header              │ │ │ │ │
│ │ │ │ │ [📄] file   │ │ │ │ [📄] file   [after] │ │ │ │ │
│ │ │ │ └─────────────┘ │ │ └─────────────────────┘ │ │ │ │
│ │ │ │ ┌─────────────┐ │ │ ┌─────────────────────┐ │ │ │ │
│ │ │ │ │ Code Area   │ │ │ │ Code Area           │ │ │ │ │
│ │ │ │ │ - Syntax    │ │ │ │ - Syntax            │ │ │ │ │
│ │ │ │ │ - Diff (-) │ │ │ │ - Diff (+)          │ │ │ │ │
│ │ │ │ │ - Focus     │ │ │ │ - Focus             │ │ │ │ │
│ │ │ │ │ - Blur/Fade │ │ │ │ - Blur/Fade         │ │ │ │ │
│ │ │ │ └─────────────┘ │ │ └─────────────────────┘ │ │ │ │
│ │ │ └─────────────────┘ └─────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ VS Badge (centered, absolute)                   │ │ │
│ │ │ - Hidden on mobile                              │ │ │
│ │ │ - Overlays the split line                       │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

Shiki Transformer Pipeline:
┌─────────────────────────────────────┐
│ Input: beforeCode + afterCode       │
│ ↓                                   │
│ transformerNotationHighlight        │
│ - Processes // [!code highlight]    │
│ - Adds .highlighted classes         │
│ ↓                                   │
│ transformerNotationDiff             │
│ - Processes // [!code ++/--]        │
│ - Adds .add/.remove classes         │
│ ↓                                   │
│ transformerNotationFocus            │
│ - Processes // [!code focus]        │
│ - Adds .focused classes             │
│ - Blurs non-focused lines           │
│ ↓                                   │
│ Shiki Theme Application             │
│ - Applies syntax highlighting       │
│ - Theme-aware color generation      │
│ ↓                                   │
│ HTML Output with Classes            │
└─────────────────────────────────────┘

Interactive Effects:
┌─────────────────────────────────────┐
│ Hover States                        │
│ - group/left: affects left panel    │
│ - group/right: affects right panel │
│ - Removes blur on focused elements  │
│ ↓                                   │
│ Focus Detection                     │
│ - hasLeftFocus / hasRightFocus      │
│ - Auto-detected from .focused class │
│ - Controls blur/opacity effects     │
│ ↓                                   │
│ Theme Integration                   │
│ - useTheme hook integration         │
│ - Dynamic light/dark switching      │
│ - Preserves highlighting across     │
│   theme changes                     │
└─────────────────────────────────────┘

Component Composition

  • CodeComparison: Main container with responsive grid layout
  • Theme Integration: Dynamic theme switching with useTheme hook
  • Shiki Transformers: Advanced notation processing for diffs and focus
  • Interactive Effects: Hover states and focus blur effects
  • Header Elements: File icons and before/after labels
  • VS Badge: Central comparison indicator for desktop view
  • Responsive Design: Stacked layout on mobile, side-by-side on desktop
  • Custom Highlighting: Configurable highlight colors for emphasized lines
  • Accessibility: Proper selection styling and keyboard navigation support

Props

Credits

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

Built by malinskibeniamin. The source code is available on GitHub.

On this page