
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
react-native-morph-card
Advanced tools
Native card-to-modal morph transition for React Native. iOS App Store-style expand animation.
Native card-to-modal morph transition for React Native. Smoothly animates a card from a list into a fullscreen detail view, morphing size, position, and corner radius — then collapses back.
UIViewPropertyAnimator / Android ValueAnimator)npm install react-native-morph-card
# or
yarn add react-native-morph-card
cd ios && pod install
No additional steps required.
Wrap your card content in MorphCardSource. On the detail screen, use MorphCardTarget where the card should land. Use useMorphTarget for easy collapse handling.
Important:
MorphCardSourcecan wrap any React Native component (images, views, text, etc.). During the animation, the content is captured as a bitmap snapshot — but once the animation completes, the snapshot fades out and the source's children are automatically cloned intoMorphCardTargetas live React components. The cloned children are rendered at the source card's original layout dimensions, so your component layout stays consistent. This means observable values (timers, animated values, live data) will update in real time after the transition finishes. If you useresizeMode, the bitmap is kept instead (native image scaling doesn't apply to React components).
import React from 'react';
import { View, Image, Text, Pressable } from 'react-native';
import {
MorphCardSource,
MorphCardTarget,
useMorphTarget,
} from 'react-native-morph-card';
// ── List screen ──
const ListScreen = ({ navigation }) => {
return (
<MorphCardSource
width={200}
height={150}
borderRadius={16}
expandDuration={350}
onPress={(sourceTag) => navigation.navigate('Detail', { sourceTag })}
>
<Image source={albumArt} style={{ width: 200, height: 150 }} />
</MorphCardSource>
);
};
// ── Detail screen ──
const DetailScreen = ({ route, navigation }) => {
const { dismiss } = useMorphTarget({
sourceTag: route.params.sourceTag,
navigation,
});
return (
<View style={{ flex: 1 }}>
<MorphCardTarget
sourceTag={route.params.sourceTag}
width={'100%'}
height={300}
collapseDuration={200}
borderRadius={0}
/>
<Pressable onPress={dismiss}>
<Text>Close</Text>
</Pressable>
</View>
);
};
<MorphCardSource>Wraps the card content on the list/grid screen. Captures a snapshot and drives the expand animation.
| Prop | Type | Default | Description |
|---|---|---|---|
width | DimensionValue | — | Card width |
height | DimensionValue | — | Card height |
borderRadius | number | 0 | Corner radius of the card |
backgroundColor | string | — | Background color (enables "wrapper mode" where the background expands separately from the content) |
duration | number | 300 | Default animation duration in ms (used for both expand and collapse if specific durations are not set) |
expandDuration | number | — | Duration of the expand animation in ms. Overrides duration for expand. |
resizeMode | 'cover' | 'contain' | 'stretch' | 'cover' | How the snapshot scales during animation. When set, the bitmap is kept after expand (no live children). Recommended when wrapping an <Image> — without it, the image may not scale properly during the animation. |
rotations | number | 0 | Number of full 360° rotations during the expand animation |
rotationEndAngle | number | 0 | Final rotation angle in degrees after expand (e.g. 45 to end tilted). Collapse reverses it back to 0 |
onPress | (sourceTag: number) => void | — | Called on tap with the native view tag. Use this to navigate to the detail screen. |
<MorphCardTarget>Placed on the detail screen where the card should land. Triggers the expand animation on mount. After the animation, the source's children are automatically cloned here as live React components.
| Prop | Type | Default | Description |
|---|---|---|---|
sourceTag | number | required | The source view tag from navigation params |
width | DimensionValue | source width | Target width after expand |
height | DimensionValue | source height | Target height after expand |
borderRadius | number | source radius | Target corner radius. Set to 0 for no rounding. |
collapseDuration | number | — | Duration of the collapse animation in ms. Falls back to the source's duration. |
contentOffsetY | number | 0 | Vertical offset for content snapshot in wrapper mode |
contentCentered | boolean | false | Center content snapshot horizontally in wrapper mode |
useMorphTarget(options)Hook that provides a dismiss function for collapsing back to the source card. The navigation object must support goBack() — works with React Navigation, expo-router, or any navigator that implements it.
const { dismiss } = useMorphTarget({
sourceTag: route.params.sourceTag,
navigation,
});
Note: The detail screen should be presented as a modal (e.g.
transparentModalorfullScreenModalin React Navigation) so the source screen remains mounted underneath during the animation. Make sure to disable any built-in navigation transitions (e.g.animation: 'none'in React Navigation) — the morph animation replaces the screen transition entirely, and combining both will look broken.
For more control, use the imperative functions:
import {
morphExpand,
morphCollapse,
getViewTag,
} from 'react-native-morph-card';
// Expand from source to target
await morphExpand(sourceRef, targetRef);
// Collapse back (pass the sourceTag)
await morphCollapse(sourceTag);
// Get the native view tag from a ref
const tag = getViewTag(viewRef);
## Running the example app
The example app lives in the `example/` directory and uses [`react-native-test-app`](https://github.com/nicklasmoeller/react-native-test-app) to manage the native projects.
### Prerequisites
| Tool | Version |
|------|---------|
| Node.js | >= 18 |
| Yarn | 1.x |
| Ruby | >= 2.7 (for CocoaPods) |
| CocoaPods | ~> 1.15 |
| Xcode | >= 15 (iOS) |
| Android Studio | latest (Android) |
| JDK | 17 |
Make sure you have an iOS Simulator or Android Emulator available.
### 1. Install dependencies
From the repository root:
```sh
# Install root (library) dependencies
yarn install
# Install example app dependencies
cd example
yarn install
# Install CocoaPods (from example/ios)
cd ios
bundle install
bundle exec pod install
cd ..
# Start Metro and build
yarn ios
This opens the app on the iOS Simulator. Metro starts automatically.
If you prefer to build from Xcode, open example/ios/MorphCardExample.xcworkspace and press Run.
Make sure an Android emulator is running (or a device is connected), then from example/:
yarn android
Gradle will download dependencies on first run — this can take a few minutes.
If you want to start the Metro bundler on its own (e.g. to see logs in a dedicated terminal):
cd example
yarn start
Then run yarn ios or yarn android in another terminal.
Only needed if you want to test pre-built bundles (not required for normal development):
cd example
yarn build:ios
yarn build:android
| Problem | Fix |
|---|---|
pod install fails | Run bundle install first, then bundle exec pod install |
| Android build fails on first run | Make sure ANDROID_HOME is set and an emulator/device is available |
Metro can't find react-native-morph-card | Run yarn install at the repo root first |
| Duplicate module errors | Delete node_modules in both root and example/, then reinstall |
Contributions are welcome! If you find a bug or have a feature request, please open an issue. Pull requests are appreciated — just make sure to open an issue first so we can discuss the approach.
MIT
FAQs
Native card-to-modal morph transition for React Native. iOS App Store-style expand animation.
The npm package react-native-morph-card receives a total of 50 weekly downloads. As such, react-native-morph-card popularity was classified as not popular.
We found that react-native-morph-card demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.