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.

App.jsx
// 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.

PartWebReact Native
Transforms and opacityWeb Animations APIAnimated, native driver
Width and heightWeb Animations APIAnimated, JS driver
Streamed textFade-in characters, a few React renders per secondA real Text, no fade
Sheets and zoomNative dialog in the top layerTransparent Modal
BackgroundIn a hidden tab, streamed text shows at onceMotion 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, numberOfLines and accessibility behave as usual.
  • MotionSheet and MotionZoom render in a transparent Modal, 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.
  • MotionHold confirms directly from the accessibility activate action.
  • Inline MotionSwap measures new content on one line; use inline=— for content that wraps.
Screen.native.jsx
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.

Search

Type to search the documentation.