Patterns · AI
Conversation
Chat layout: a scrolling message list that follows new content, with a sticky composer underneath.
import { Conversation } from '@nexub/patterns';Usage
A full chat or assistant view: messages above, composer below.
A single question and answer: a PromptInput and a MessageBubble in normal flow are enough.
Comment threads that don’t follow new content: use ActivityFeed.
Examples
Mini chat
Send a message: it shows Thinking, then streams a cited reply. Stop or Escape ends the reply early.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | The messages, usually MessageBubbles. |
| composer | ReactNode | — | Sticky slot under the list, usually a PromptInput. |
| autoScroll | boolean | true | Follow new content while the reader is at the bottom. Scrolling up stops following and shows "Jump to latest". |
| announce | boolean | false | Make the list a polite role="log". Only for whole-message updates: with token streaming it announces every chunk. |
| messages | Partial<ConversationMessages> | — | Overrides for jumpToLatest and conversation. |
On iOS & Android: ChatScreen
import { ChatScreen } from '@nexub/react-native/patterns';
<ChatScreen messages={messages} onSend={send} thinking={streaming} />Web vs mobile
Same tokens and prop names. Where the platforms differ:
| Web | iOS & Android | |
|---|---|---|
| Composer | PromptInput with attachments and shortcuts. | Composer pinned above the keyboard; send on the return key. |
Interactive preview of @nexub/react-native rendered for the web. Native chrome (switches, pickers, Liquid Glass) looks like the platform on a device.
On device

iPhone (iOS simulator)

Pixel (Android emulator)
Screenshots from the latest CI run of the showcase app; the live frame renders the same code for the web.
ChatScreen props
| Prop | Type | Default | Description |
|---|---|---|---|
| messagesrequired | ChatMessage[] | — | — |
| onSendrequired | (text: string) => void | — | — |
| thinking | boolean | — | Assistant is thinking (before the first token). |
| placeholder | string | — | — |
| empty | React.ReactNode | — | — |