Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Diff

Line-based text diff viewer with inline and side-by-side display modes.

Components Diff
data static
<arc-diff>

Overview

Diff compares two blocks of text line by line and renders a color-coded visualization of the changes. Added lines appear with a green-tinted background and a `+` prefix, removed lines appear with a red-tinted background, strikethrough text, and a `-` prefix, and unchanged lines display in a muted secondary color with a blank prefix. The component uses a longest-common-subsequence algorithm to compute the minimal diff between the `before` and `after` text props. No external diff libraries are required — the algorithm runs entirely inside the component. Two display modes are available via the `mode` prop. The default `inline` mode renders all changes in a single scrollable column, interleaving additions and removals in reading order. The `side-by-side` mode splits the view into a CSS grid with two equal-width panes separated by a subtle border — the left pane shows the original text (with removals highlighted) and the right pane shows the modified text (with additions highlighted). Line numbers are displayed in a fixed-width gutter column. The entire viewer uses the monospace font stack and code-sized typography tokens for a terminal-like reading experience. The container supports horizontal scrolling for long lines with thin styled scrollbars. Diff is designed for code review panels, changelog overlays, configuration comparisons, and anywhere a developer-facing UI needs to show what changed between two versions of text content.

Guidelines

When to use

  • Use short, focused text snippets — diffs work best with fewer than 100 lines
  • Set mode="side-by-side" when horizontal space allows for easier comparison
  • Pair with a heading or label to describe what is being compared
  • Use for code snippets, configuration files, or any line-oriented text
  • Wrap in a container with a max-height and overflow-y: auto for very long diffs

When not to use

  • Do not pass binary or non-text content as before/after values
  • Do not use Diff for single-character or word-level highlighting — it operates on whole lines
  • Do not embed interactive elements inside the before or after strings
  • Do not use side-by-side mode in narrow containers where columns would be too cramped

Features

  • LCS-based line diff algorithm with no external dependencies
  • Inline mode interleaves additions and removals in a single column
  • Side-by-side mode renders two panes in a CSS grid with a subtle divider
  • Color-coded lines: green for added, red with strikethrough for removed, muted for unchanged
  • Line number gutter with non-selectable numbers for clean copy-paste
  • Prefix markers (+, -, space) in a fixed-width column for scanning
  • Monospace font stack with code-size typography tokens
  • Horizontal scroll with thin styled scrollbars for long lines
  • Exposed CSS parts (container, line, line-number, prefix) for external style overrides
  • Respects `prefers-reduced-motion` for transitions

Preview

Usage

<arc-diff
  original="const name = 'World';
console.log('Hello');
return name;"
  revised="const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;">
</arc-diff>

<!-- Side-by-side mode -->
<arc-diff mode="side-by-side"
  original="line one
line two
line three"
  revised="line one
line 2
line three
line four">
</arc-diff>
import { Diff } from '@arclux/arc-ui-react';

export default function Example() {
  return (
    <>
      <Diff
        original={`const name = 'World';
      console.log('Hello');
      return name;`}
        revised={`const name = 'ARC UI';
      console.log('Hello');
      console.log('Welcome');
      return name;`}
      />

      {/* Side-by-side mode */}
      <Diff mode="side-by-side"
        original="line one\nline two\nline three"
        revised="line one\nline 2\nline three\nline four"
      />
    </>
  );
}
<script setup>
import { Diff } from '@arclux/arc-ui-vue';

const original = `const name = 'World';
console.log('Hello');
return name;`;

const modified = `const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;`;
</script>

<template>
  <Diff :original="original" :revised="modified" />
  <Diff mode="side-by-side" :original="original" :revised="modified" />
</template>
<script>
  import { Diff } from '@arclux/arc-ui-svelte';

  const original = `const name = 'World';
console.log('Hello');
return name;`;

  const modified = `const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;`;
</script>

<Diff original={original} revised={modified} />
<Diff mode="side-by-side" original={original} revised={modified} />
import { Component } from '@angular/core';
import { Diff } from '@arclux/arc-ui-angular';

@Component({
  imports: [Diff],
  template: `
    <arc-diff
      [before]="original"
      [after]="modified">
    </arc-diff>
    <arc-diff mode="side-by-side"
      [before]="original"
      [after]="modified">
    </arc-diff>
  `,
})
export class MyComponent {
  original = `const name = 'World';
console.log('Hello');
return name;`;

  modified = `const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;`;
}
import { Diff } from '@arclux/arc-ui-solid';

const original = `const name = 'World';
console.log('Hello');
return name;`;

const modified = `const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;`;

<Diff original={original} revised={modified} />
<Diff mode="side-by-side" original={original} revised={modified} />
import { Diff } from '@arclux/arc-ui-preact';

const original = `const name = 'World';
console.log('Hello');
return name;`;

const modified = `const name = 'ARC UI';
console.log('Hello');
console.log('Welcome');
return name;`;

<Diff original={original} revised={modified} />
<Diff mode="side-by-side" original={original} revised={modified} />

API

original string ''
The original text to compare (split by newlines).
revised string ''
The modified text to compare (split by newlines).
mode 'inline' | 'side-by-side' 'inline'
Display mode: 'inline' renders changes in a single column, 'side-by-side' renders two panes in a grid.

See Also