Image compare

Drag a divider across two images to see what changed.

pnpm dlx shadcn@latest add @uiarc/image-compare
Live · keyboard ready
Final grade of the same room, with warmer light and richer wood tones
Raw capture of a bright living room with timber beams and arched windows, flat and muted
Living roomRaw capture and final grade
  • Before and after visuals such as photo edits, redesigns, or cleanup results.
  • Top and bottom comparisons, via orientation vertical.
  • Use carousel to browse many images.
  • Use resizable-panels to split live content rather than images.

Installation

Add Image compare with the shadcn CLI, or copy the source by hand.

pnpm dlx shadcn@latest add @uiarc/image-compare

Adds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:

example.tsx
import { ImageCompare } from "@/registry/components/image-compare/image-compare"; export function Retouch() {  return (    <ImageCompare      before={<img src="/photo-raw.jpg" alt="Unedited photo" />}      after={<img src="/photo-edit.jpg" alt="Retouched photo" />}      aspectRatio="4 / 3"    />  );}

ImageCompare

A before and after slider with a draggable divider over two stacked images.

PropTypeDefaultDescription
beforeRequiredReactNode–Original, shown left or top. Pass an image with its own alt text.
afterRequiredReactNode–Result, shown right or bottom.
positionnumber–Controlled divider position in percent from the left or top.
defaultPositionnumber50Initial position when uncontrolled.
onPositionChange(position: number) => void–Called when the divider settles on a new position.
orientation"horizontal" | "vertical""horizontal"Vertical stacks images top and bottom; changing it swings the divider.
labels[string, string] | false["Before", "After"]Captions over each side. False hides them.
labelstring"Before and after"Accessible name of the divider.
aspectRatiostring"3 / 2"Frame proportions as a CSS aspect-ratio.
classNamestring–Class for the root.
Arrow keys
Moves the divider by 1 percent, or 10 with Shift.
PageUporPageDown
Moves the divider by 10 percent.
HomeorEnd
Shows all of the before or all of the after image.
Double click
On the handle, recenters the divider.
  • The handle is a focusable role="slider" with aria-orientation and aria-valuetext like "40% after".
  • Caption chips are aria-hidden; give both images meaningful alt text.
  • Dragging works anywhere on the frame, not only on the handle.
  • The divider follows the pointer and settles with release velocity; the handle stretches into a capsule while dragging.
  • Keyboard presses at an edge give a small bump; captions fade as the divider reaches them.
  • Reduced motion jumps the divider and handle without springs.
  • The frame is full width with a fixed aspect ratio, so it scales to any column.
  • On touch the photo waits for a sideways drag before moving the divider, so vertical swipes still scroll the page; a tap jumps the divider there.
  • The divider runs on motion values and one ResizeObserver, with no React re-render per drag frame.
  • Both images stay mounted and stacked, so size them for the frame.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for visual diffs: photo edits, redesigns, before and after results. Use carousel to browse many images.
  • Both images should share the same crop and size so the reveal lines up.

The full library index for assistants is at /llms.txt.