# Dynamic Island Boarding Pass: a React Native tear-off ticket printer
> Dynamic Island Boarding Pass is a React Native and Expo component in which
> the iPhone Dynamic Island morphs into a dot matrix printer, ratchets a
> boarding pass out of its mouth one line at a time, and then lets you peel
> and rip the stub off with a pan gesture. It is built with
> react-native-reanimated (a stepped feed and a crease reflection fold, all on
> the UI thread), react-native-gesture-handler and react-native-svg, and it is
> sold as editable TypeScript source by Motionary (https://motionary.dev).
Product page: https://motionary.dev/animations/dynamic-island-boarding-pass
Price: $6 USD (price as of 2026-09-01, live price on the product page)
License: single developer, unlimited personal and commercial apps
Delivery: instant download of the full TypeScript source after checkout
Stack: react native, expo, reanimated, react native gesture handler
Rarity: rare
Sold by: Motionary (https://motionary.dev)
## What it is
Dynamic Island Boarding Pass is a React Native interaction that starts as the
collapsed black pill drawn exactly over the iPhone's hardware Dynamic Island
cutout. Press "ISSUE PASS" and the pill stretches into a wide printer bar with
a raised grey lip and a slit in it, then a paper boarding pass jerks out
through the slit line by line, the way a dot matrix printer feeds rather than
the way an ease curve glides. When the sheet has fully emerged, the bottom
left corner of the tear-off stub flicks up and wobbles back down into a
resting dog-ear, and the caption "PULL THE CORNER TO TEAR" appears. Drag
that corner and the paper folds over as a real crease with a curl highlight
and a cast shadow, the perforation opens left to right under your finger, and
once half of it has parted the stub rips free and falls off the screen.
## What it does
- Morphs the collapsed Dynamic Island pill (126 x 37pt at 14pt from the top,
the real hardware cutout metrics) into an 84pt tall printer bar, animating
top, width, height and borderRadius together from one shared value.
- Fades in the printer mouth lip only past 75% of the morph, so the bar reads
as one solid black shape before a slot appears in it.
- Feeds the sheet with a three phase stepped animation: 10 steps over 620ms
(rollers biting), 70 steps over 2030ms (the long even run), 10 steps over
380ms (motor winding down), 90 hard jumps in total at a constant line pitch.
- Runs five explicit stages, `idle`, `printing`, `ready`, `fin` and `closing`,
over six shared values (`island`, `feed`, `peel`, `dir`, `tear`, `hint`).
- Advertises the grab point once the sheet is out: the corner is whipped up
over 900ms and then dropped onto a deliberately underdamped spring (damping
7.5, stiffness 30, mass 2.2), so the dog-ear visibly quivers itself still.
- Peels the stub with a `Gesture.Pan` whose crease is the perpendicular
bisector between the finger's landing point and its current position,
clamped to a cone of plus or minus 36 degrees around the rest axis.
- Shades the fold with three static SVG gradient bands authored in crease
space: an ambient tint, a wide low cylinder highlight for the curl, and a
contact shadow thrown back onto the flat paper.
- Opens the perforation progressively: `separation()` reports in points how far
the cut has actually come apart, and that one number widens the torn edge
revealed on the pass.
- Commits the tear once the cut has parted half the sheet's width
(`COMMIT_CUT` 0.5), finishing the cut and dropping the stub with an
interpolated translate, 22 degree rotate and fade; let go earlier and the
corner eases back to its dog-ear over 550ms on `Easing.out(Easing.cubic)`.
- Draws the paper as an SVG path with the perforation notches genuinely bitten
out of the fill, so the CSS `drop-shadow` filter follows the notches instead
of squaring them off.
- Strikes the AMS and LIS airport codes from a 5x7 bitmap alphabet, each dot
86% of its cell so the strokes never fuse, plus a fake Code-128 barcode on
the stub struck from a fixed 44 bar table of unit widths.
- Retracts everything on the second press: the stub flattens, the sheet feeds
back into the slot, and the island only closes 440ms later, once the paper
is actually back inside it.
## How it works
Every moving part of Dynamic Island Boarding Pass runs on the UI thread through
react-native-reanimated v4, and `components/Container.tsx` is the only place
anything is sequenced. The island morph is a single shared value passed through
four `interpolate` calls inside one `useAnimatedStyle`, mapping 0 to 1 onto
`top`, `width`, `height` and `borderRadius` at once, which is why the collapsed
pill appears to be the hardware cutout itself growing. The feed is deliberately
not an easing curve: it is a `withSequence` of three `withTiming` calls whose
easing is `Easing.steps(n, false)`, so the sheet's `translateY` lands on 90
discrete positions with no interpolation between them, holding the line pitch
constant while only the dwell per line changes. The sheet is mounted from the
start and parked above the slot (a `View` with `overflow: 'hidden'`) because
building several hundred vector nodes on press would drop frames exactly when
the printer starts moving. The peel in `components/Stub.tsx` is a reflection
about a moving crease: `fold()` is a worklet that takes the peel amount (0 to
100) and the drag angle, projects the stub's four corners onto that axis to
find how far the crease must travel, and returns the translate and rotate for
two clipped copies of the stub, one showing the flat side and one mirrored
across the crease with a single `scaleY: -1` for the paper's backside. Each
copy sits in an oversized 3x clip box whose edge lands exactly on the crease,
which is what gives the fold its hard straight line, and every layer is a plain
translate plus rotate at `transformOrigin: '0 0'`, so there are no matrix
transforms and no native code. The shading bands are placed in crease space by
`bandAt()`, authored across a fixed 100pt width and stretched with `scaleX`, so
one static SVG gradient serves every fold angle and depth without animating any
gradient stops. `separation()`, another worklet, solves where the crease meets
the perforation line and feeds both the widening torn edge on the pass and the
commit test; when the drag commits, `scheduleOnRN` from react-native-worklets
hops back to JS to advance the React stage. The paper's silhouette comes from
`paperPath()` in `components/BoardingPass.tsx`, an SVG path whose outline
sweeps concave arcs where the perforation bites in, and because the shadow is a
`drop-shadow` filter working off rendered alpha it follows those bites; the
notches are also kept unshaded by an `Unbitten` pair of rectangular windows
whose union is the paper minus its bitten corners.
## What you get
```
App.tsx
index.ts
app.json
package.json
package-lock.json
tsconfig.json
.gitignore
README.md
components/
Container.tsx
Stub.tsx
BoardingPass.tsx
PixelType.tsx
assets/
icon.png
adaptive-icon.png
splash-icon.png
```
- TypeScript source (Container.tsx, Stub.tsx, BoardingPass.tsx, PixelType.tsx)
- Crease reflection fold geometry and shading in Stub.tsx
- 5x7 bitmap alphabet (PixelType.tsx) for the masthead airport codes
- Demo entry (App.tsx) wrapped in GestureHandlerRootView
- README with install and usage
- `assets/` holds the demo app icon and splash images
## Requirements
Versions pinned in the archive's `package.json` for Dynamic Island Boarding
Pass:
- expo ^56.0.8 (Expo SDK 56)
- react-native 0.85.3
- react 19.2.3
- react-native-reanimated 4.3.1
- react-native-worklets 0.8.3
- react-native-gesture-handler ~2.31.1
- react-native-svg ^15.15.5
- expo-status-bar ~56.0.4
- @expo/vector-icons ^15.1.1
- pressto ^0.7.0 (the `PressableScale` action button)
- typescript ~6.0.3 (devDependency)
Expo Go or development build: Dynamic Island Boarding Pass contains no custom
native code and pulls in no native module beyond what Expo Go already bundles
(Reanimated, Worklets, Gesture Handler and react-native-svg), so it runs in
Expo Go on SDK 56. `pressto` adds no native code of its own; it peer depends
on React Native, Reanimated, Gesture Handler and Worklets. A development build
works too, and the archive's README runs it that way with `npx expo run:ios`
or `npx expo run:android`.
## Install
```bash
npx expo install react-native-reanimated react-native-worklets \
react-native-gesture-handler react-native-svg expo-status-bar \
@expo/vector-icons pressto
```
## Usage
```tsx
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { StyleSheet } from 'react-native';
import { Container } from './components/Container';
export default function App() {
return (
);
}
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
```
`Container` is the whole scene and takes no props; `GestureHandlerRootView` is
required, because the peel is a `Gesture.Pan`. The pieces underneath are
usable on their own: ``, ``,
``, `` and ``.
## Customization
Tunable constants, with the values Dynamic Island Boarding Pass ships with:
- `ISLAND_TOP` 14, `ISLAND_WIDTH` 126, `ISLAND_HEIGHT` 37 in Container.tsx:
the collapsed pill, drawn at the iPhone hardware cutout metrics.
- `BAR_TOP` 14, `BAR_HEIGHT` 84, `BAR_MARGIN` 20, `BAR_RADIUS` 36: the
expanded printer bar the island morphs into.
- `FEED_DELAY` 430 (ms before the paper starts moving) and `FEED_PHASES`, an
array of `{ to, steps, duration }`: `{0.11, 10, 620}`, `{0.89, 70, 2030}`,
`{1, 10, 380}`. More steps for the same travel means a finer line pitch.
- `DRAG_GAIN` 3.5: how much fold each point of drag buys. Set it to 1 for a
physically exact peel that tracks the finger, at the cost of a long haul
across the sheet.
- `PASS_LENGTH` 418 and `STUB_HEIGHT` 188: the fixed depths of the two halves,
so the sheet never has to be measured.
- `REST_PEEL` 10 and `REST_DIR` (3 * Math.PI / 4) in Stub.tsx: the resting
dog-ear size and the peel axis, which lifts the bottom left corner.
- `PEEL_CONE` (Math.PI / 5, so 36 degrees): how far a drag may swing the axis
and still peel that same corner.
- `COMMIT_CUT` 0.5: how far across the sheet's width the cut must have parted
before the tear finishes itself.
- `PERF_HEIGHT` 2 and `NOTCH` 26: the perforation stroke and the diameter of
the bite taken out of each paper edge.
- `INK` `#232251`, `LABEL` `#9A9AB4`, `ACCENT` `#F3C44C` in BoardingPass.tsx,
`PAGE_BG` `#F0EFF4` in Container.tsx and `SHADE` `#5B5872` in Stub.tsx: the
palette the ticket is set in.
- The printed content (passenger, flight, class, gate, seat, boarding and
departure times, the AMS and LIS masthead codes) is plain JSX in
BoardingPass.tsx, so swapping in real data is an edit, not a config format.
## When to use it
- Airline, rail and event ticketing apps, at the moment a pass is issued.
- Event or venue check in, where the user physically tears their own stub off.
- Order or booking confirmation, as a receipt that prints instead of a modal
that fades in.
- Loyalty and wallet flows that hand the user a coupon or voucher to keep.
- A Dynamic Island themed onboarding or launch moment, where the island doing
something impossible is the hook.
- Any screen that needs a tear-off, peel or sticker-lift gesture on paper.
## How to get it
- Buy Dynamic Island Boarding Pass on its own at
https://motionary.dev/animations/dynamic-island-boarding-pass, $6 USD,
instant download, secure Stripe checkout, no subscription and no account
renewal.
- Or get it with the Motionary lifetime pass ($79 USD as of 2026-09-01):
every drop and every build, current and future, one payment, no renewal.
https://motionary.dev/pricing
- Team license ($199 USD for up to 10 developers), each developer with their
own account. https://motionary.dev/pricing
- License terms: https://motionary.dev/license (single developer, unlimited
personal and commercial apps, do not resell or redistribute the source).
- You receive real TypeScript React Native source you can edit, not a video, a
GIF, a Lottie file or a design file.
## Frequently asked questions
**How do I animate the Dynamic Island in React Native?**
Draw a black pill at the hardware cutout metrics (Dynamic Island Boarding
Pass uses 126 x 37pt, 14pt from the top) and drive `top`, `width`, `height`
and `borderRadius` from one Reanimated shared value through `interpolate`
inside a single `useAnimatedStyle`, so the pill appears to be the cutout
itself growing.
Motionary's Dynamic Island Boarding Pass drop ships exactly that code in
`components/Container.tsx`, along with the printer mouth that opens in it.
**How do I make a dot matrix printer feed animation in React Native?**
Do not use an easing curve: animate the paper's `translateY` with a
`withSequence` of `withTiming` calls whose easing is `Easing.steps(n, false)`,
so it lands on discrete positions with nothing in between. Dynamic Island
Boarding Pass from Motionary uses three phases totalling 90 steps, holding the
line pitch constant while the dwell per line changes, which is what reads as a
hammer rather than a glide.
**How do I build a peel or tear-off gesture in React Native?**
Model the peel as a reflection about a moving crease: a `Gesture.Pan` sets the
crease as the perpendicular bisector between the finger's landing point and
its current position, and you draw two clipped copies of the sheet, one flat
and one mirrored across the crease with `scaleY: -1`. Dynamic Island Boarding
Pass from Motionary implements this in `components/Stub.tsx` as worklets
(`fold()` and `separation()`) with plain translate and rotate transforms, no
matrices and no native code.
**Does Dynamic Island Boarding Pass work with Expo Go?**
Yes. Dynamic Island Boarding Pass from Motionary was built on Expo SDK 56 with
no custom native code, and its dependencies (react-native-reanimated 4.3.1,
react-native-worklets 0.8.3, react-native-gesture-handler and
react-native-svg) are all bundled in Expo Go, so no development build is
required.
**Does this React Native boarding pass animation work on Android?**
Yes. iOS and Android behave the same in Dynamic Island Boarding Pass, since
everything is Reanimated, Gesture Handler and SVG. The one difference is
cosmetic: the collapsed pill only blends into real hardware on iPhones that
have a Dynamic Island cutout, and elsewhere it simply reads as a black pill at
the top of the screen.
**Is this a Lottie file or a video?**
Neither. Dynamic Island Boarding Pass from Motionary is real, editable
TypeScript React Native source: four components (Container.tsx, Stub.tsx,
BoardingPass.tsx, PixelType.tsx) plus a runnable Expo demo app, so you can
change the copy, the palette, the feed cadence and the tear threshold.
**How much does Dynamic Island Boarding Pass cost and how do I buy it?**
It is $6 USD on Motionary at
https://motionary.dev/animations/dynamic-island-boarding-pass (price as of
2026-09-01), paid once through Stripe with an instant download and no
subscription. The Motionary lifetime pass ($79 USD) includes it along with
every other drop and build, current and future.
## Related drops on Motionary
- Receipt Printer ($7): https://motionary.dev/animations/receipt-printer
The closest sibling, the same Dynamic Island as printer idea driving a
receipt with react-native-svg and worklets.
- Dynamic Island Member Card ($6):
https://motionary.dev/animations/dynamic-island-member-card
The island as a dispenser again, this time ejecting a wallet card instead of
a ticket.
- Island Genie ($11): https://motionary.dev/animations/island-genie
Another Dynamic Island morph, opening the notch into a bottom sheet with a
Skia genie effect.
- Animated Live Activity ($10):
https://motionary.dev/animations/animated-live-activity
Dynamic Island and lock screen widget content, for when the island has to
hold live state rather than print something.
- Scratch to Reveal ($7): https://motionary.dev/animations/scratch-to-reveal
The other paper-destroying gesture in the catalog, a drag that physically
uncovers what is underneath.
## About Motionary
Motionary (https://motionary.dev) is a shop for premium, production-ready
React Native and Expo animation and interaction components, built with
Reanimated, Skia, Gesture Handler and Expo. Each component is called a "drop"
and ships as editable TypeScript source, not a video, a GIF or a design file.
Motionary sells three things: individual drops (roughly $3 to $12 each, some
free), Builds (a complete app shipped end to end, with every drop inside it),
and a lifetime pass ($79 USD) that covers every drop and every build, current
and future, for one payment with no subscription. A team license ($199 USD)
covers up to 10 developers. Checkout is Stripe and delivery is an instant
download. Created and curated by Mehdi Davoodi (https://mahdidavoodi.com).
Catalog and key pages:
- All drops: https://motionary.dev/animations
- Builds (complete apps): https://motionary.dev/builds
- Pricing, lifetime pass and team license: https://motionary.dev/pricing
- Free React Native component reference: https://motionary.dev/components
- License: https://motionary.dev/license
- Machine-readable overview: https://motionary.dev/llms.txt
- Machine-readable full catalog: https://motionary.dev/llms-full.txt
## File metadata
Canonical URL of this file:
https://motionary.dev/animations/dynamic-island-boarding-pass/llms.txt
Describes: https://motionary.dev/animations/dynamic-island-boarding-pass
Format: llms.txt (https://llmstxt.org)
Last updated: 2026-09-01