Guides · 02
Web and React Native
One import for both platforms. Metro selects the native implementation and web bundlers select the DOM one.
The same import
Install one package and import from its root on both platforms. React is the only required peer; React Native is an optional peer for native apps. Neither platform needs a provider, wrapper or setup call.
// Web and React Native: the same import.
import { MotionNumber, MotionList } from '@kkwaenggwari/animated-chorus';
export function Score({ points, players }) {
return (
<>
<MotionNumber value={points} />
<MotionList items={players} renderItem={(player) => player.name} />
</>
);
}How motion plays
On the web, components play on the Web Animations API with springs sampled analytically, so there is no animation library to load and no React render per frame. On React Native, components use Animated with the native driver for transforms and opacity, and the JS driver only where layout (width or height) changes.
| Part | Web | React Native |
|---|---|---|
| Transforms and opacity | Web Animations API | Animated, native driver |
| Width and height | Web Animations API | Animated, JS driver |
| Streamed text | Fade-in characters, a few React renders per second | A real Text, no fade |
| Sheets and zoom | Native dialog in the top layer | Transparent Modal |
| Background | In a hidden tab, streamed text shows at once | Motion settles to its end state |
React Native specifics
The API is the same; these are the differences you will notice on a device.
- Numbers and streamed text stay a real
Text, so selection, wrapping,numberOfLinesand accessibility behave as usual. MotionSheetandMotionZoomrender in a transparentModal, and the back button closes them.- Inner
ScrollViews in a sheet keep their own gestures; the sheet is dragged by its handle and static areas. MotionHoldconfirms directly from the accessibility activate action.- Inline
MotionSwapmeasures new content on one line; useinline=—for content that wraps.
import { Text, View } from 'react-native';
import { MotionNumber, MotionSheet } from '@kkwaenggwari/animated-chorus';
export function Wallet({ balance, open, setOpen }) {
return (
<View>
<MotionNumber
value={balance}
intl
locale="en-US"
format={{ style: 'currency', currency: 'USD' }}
/>
<MotionSheet open={open} onOpenChange={setOpen} detents={[0.5, 0.9]}>
<Text>Recent activity</Text>
</MotionSheet>
</View>
);
}Your layout stays yours
Components keep the platform's own layout: text metrics, wrapping, font scaling, parent constraints and your styles. Motion never forces a character width, a fixed text height or a clipping mask onto your text.
What is verified where
Web behavior is verified in real browsers. React Native behavior is covered by tests of the shared models and a mocked renderer, so check gestures and layout on your target devices before a release.