Before and after

Free · MITReact Native · Expo

Drag a handle across two pictures to compare them. The handle follows the finger on the UI thread, with a cue at the midpoint and at each end, and plays one short sweep on mount to show it can be dragged.

View as Markdown
Try it on your phone
Scan to open this demo in your phone's browser and use it with your fingers.

Installation

$ npx shadcn@latest add https://goodui.dev/native/r/before-after.json

Then run npx expo install --fix so react-native-gesture-handler, react-native-reanimated, react-native-svg match your Expo SDK. Files land in components/goodui-native/before-after.

Usage

import { BeforeAfter } from "@/components/goodui-native/before-after/before-after";

<BeforeAfter before={require("./photo.jpg")} after={{ uri: resultUrl }} aspectRatio={4 / 5} />

When to use

Use it for
  • Showing what a photo tool changed: restoring, retouching, restyling.
  • Any pair of pictures with the same framing.
Reach for something else
  • Two unrelated pictures: the comparison means nothing unless they line up.
  • Comparing more than two versions: use a carousel.

API reference

PropTypeDefault
before*ImageSourcePropType—
after*ImageSourcePropType—
aspectRatio
Width over height.
number0.8
hint
Plays one short sweep on mount to show it can be dragged.
booleantrue
labelsPartial<BeforeAfterLabels>—
style
Style for the outer container.
StyleProp<ViewStyle>—
testID
Identifier for end-to-end tests.
string—

Motion and haptics

  • The split tracks the finger directly, the knob lifts while held, and the mount sweep settles on a spring.
  • The Before and After tags fade as the handle reaches them.
  • Reduced motion: no mount sweep.
  • Haptic: drag-start once a drag begins, a tick at the midpoint, drop at each end.
  • The handle and clip update on the UI thread without re-rendering React.

Accessibility

  • An adjustable element that reads the share of the after image shown: increment and decrement move the split by 10 percent.

Notes for AI

  • Give both images the same framing and pass the true aspectRatio (width over height). Both are cropped with cover.
  • It stays left to right under RTL because pictures are physical. Do not mirror it.
  • The gesture yields to vertical scrolling, so it is safe inside a ScrollView.