React Native was the second-class citizen in the CopilotKit ecosystem. The package shipped hooks and transport, but rendering was entirely on you. With v1.58.0, that changes.
The @copilotkit/react-native package now includes a full pre-built chat surface: CopilotChat, CopilotModal, chat bubble components (AssistantMessage and UserMessage), a TypingIndicator animation, and a CopilotMarkdown component for streaming-friendly markdown in AI responses.
CopilotChat is built on FlatList with extraData-driven re-renders for correctness. It handles tool-call rendering via a useRenderToolRegistry, error states, an empty state with suggestion pills, and a KeyboardAvoidingView wrapper. It also accepts a FlatListComponent prop so you can swap in a bottom-sheet-compatible list without forking the component.
CopilotModal takes a different approach. It uses @gorhom/bottom-sheet's BottomSheetFlatList for gesture-safe scrolling, exposes configurable snap points, and gives you an imperative open() / close() API. There is a disableKeyboardAvoiding prop for cases where you are already embedding it inside another keyboard-aware view and do not want double-avoidance.
Tool rendering is wired through a new useRenderTool hook backed by RenderToolContext. State is managed via useSyncExternalStore. The RenderToolProvider is auto-wrapped by CopilotKitProvider, so no extra setup is required on your end.
Markdown streaming uses Software Mansion Labs' react-native-streamdown under the hood, surfaced as the CopilotMarkdown component. This means AI responses render progressively as tokens arrive, matching the feel of the web SDK.
To install the React Native package:
npm install @copilotkit/react-native@1.58.0
The rest of the ecosystem, including @copilotkit/react-core, @copilotkit/react-ui, and @copilotkit/runtime, is also republished at 1.58.0.
If you are building a React Native app with CopilotKit today, the practical step is straightforward: swap out your hand-rolled chat UI for CopilotChat or CopilotModal. If you are using a bottom sheet library, pass your component via the FlatListComponent prop and set disableKeyboardAvoiding. The headless approach still works if you need it, but there is no longer a reason to build the chat surface from scratch.