Platform notes
Android
Keyboard configuration
If you are using Create React Native App / Expo, no Android specific installation steps are required. Otherwise, we recommend modifying your project configuration:
Make sure you have android:windowSoftInputMode="adjustResize" in your AndroidManifest.xml:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
For Expo, you can append KeyboardAvoidingView after Chat (Android only):
<View style={{ flex: 1 }}>
<Chat />
{Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />}
</View>
Web (react-native-web)
Install the web renderer alongside the library:
yarn add react-native-web react-dom
Expo / Metro (recommended) - no extra config
npx expo start --web
Nothing else to set up. Metro runs Babel over node_modules, so this package's JSX and its Reanimated worklets get transpiled the same way your own code does. The example app runs on web exactly like this.
Other bundlers (webpack, Vite, Next.js) - the package must be transpiled
The published files are ES modules with JSX left in place, and the component uses Reanimated worklets, which need react-native-reanimated/plugin to run. Bundlers that skip node_modules when transpiling - webpack's babel-loader does by default - will choke on that. So outside Metro you need to:
- Alias
react-nativetoreact-native-weband let the resolver pick up.web.js/.web.tsxextensions - Run
@kesha-antonov/react-native-chat- and the React Native packages it depends on - through Babel with@react-native/babel-presetandreact-native-reanimated/plugin, instead of excluding all ofnode_modules
In Next.js that is transpilePackages in next.config.js; in a plain webpack setup it means widening the babel-loader rule's exclude so these packages are included.
React Strict DOM
Works inside an RSD tree - verified on iOS and Expo web
Chat drops into a React Strict DOM app unchanged. RSD's native build renders through React Native, so <Chat> is just another RN subtree:
import { css, html } from 'react-strict-dom'
import { Chat } from '@kesha-antonov/react-native-chat'
const styles = css.create({
root: { display: 'flex', flexDirection: 'column', height: '100%' },
})
<html.div data-layoutconformance='strict' style={styles.root}>
<Chat messages={messages} onSend={onSend} user={user} />
</html.div>
Three things to know:
- Web needs
react-native-web. RSD's web build contains no React Native code at all, so Chat does not resolve there on its own. Expo web gives youreact-native-webalready, so RSD (real DOM) and Chat (RNW's DOM output) render side by side in one tree. A Vite or Next.js RSD app has to add the alias and transpile step from the section above - Metro needs
unstable_enablePackageExports: true. RSD publishes only anexportsmap with nomain, so with package exports off it fails to resolve. This is the default on recent Expo SDKs - StyleX styles do not reach Chat. It takes React Native style objects and its own
themeprop, notcss.createoutput. On native,compat.nativeis the bridge if you want RSD to drive a wrapper around it