expo-ai-elements 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -0
- package/package.json +112 -0
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# expo-ai-elements
|
|
2
|
+
|
|
3
|
+
**Open-source AI chat UI components for React Native** — bring ChatGPT-level interfaces to your mobile app in minutes.
|
|
4
|
+
|
|
5
|
+
The React Native port of [Vercel AI Elements](https://elements.ai-sdk.dev). Drop-in, composable, and ready for production.
|
|
6
|
+
|
|
7
|
+
Built with [React Native Reusables](https://reactnativereusables.com) (shadcn/ui for RN) + [Uniwind](https://uniwind.dev) (Tailwind CSS for RN).
|
|
8
|
+
|
|
9
|
+
## Why expo-ai-elements?
|
|
10
|
+
|
|
11
|
+
Building AI chat UIs on mobile is painful. You need streaming markdown, code blocks with monospace fonts, LaTeX rendering, tool call displays, reasoning traces — all performing smoothly at 60fps on native.
|
|
12
|
+
|
|
13
|
+
**expo-ai-elements** gives you 25 production-ready components that handle all of this out of the box:
|
|
14
|
+
|
|
15
|
+
- **Streaming markdown** — throttled native rendering with LaTeX math support
|
|
16
|
+
- **Native markdown with LaTeX** — inline `$math$` and block `$$equations$$` rendered natively
|
|
17
|
+
- **Copy-paste architecture** — follows the shadcn/ui pattern, you own every line of code
|
|
18
|
+
- **Dark/light mode** — automatic theme support via Uniwind
|
|
19
|
+
- **Vercel AI SDK compatible** — works with `useChat` and `useCompletion` hooks
|
|
20
|
+
|
|
21
|
+
## Components
|
|
22
|
+
|
|
23
|
+
**25 components** across 6 categories:
|
|
24
|
+
|
|
25
|
+
| Category | Components |
|
|
26
|
+
|---|---|
|
|
27
|
+
| **Chat** | Conversation, Message, MessageResponse, Suggestion, Checkpoint, Citation, Streaming LaTeX |
|
|
28
|
+
| **Code** | CodeBlock, Terminal, StackTrace, TestResults, SchemaDisplay |
|
|
29
|
+
| **Reasoning** | Reasoning, ChainOfThought, Tool, Plan, Task, Agent |
|
|
30
|
+
| **Content** | Artifact, FileTree, WebPreview, Attachments |
|
|
31
|
+
| **Input** | PromptInput, SpeechInput, OpenInChat |
|
|
32
|
+
| **Utilities** | Shimmer |
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Install dependencies
|
|
38
|
+
bun install
|
|
39
|
+
|
|
40
|
+
# Run on iOS
|
|
41
|
+
npx expo run:ios
|
|
42
|
+
|
|
43
|
+
# Run on Android
|
|
44
|
+
npx expo run:android
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The app includes a built-in component showcase (Storybook-like) with interactive demos for every component, plus a full chat demo with simulated streaming.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
Components follow the shadcn/ui copy-paste pattern. Copy any file from `components/ai/` into your project:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Message, MessageContent, MessageResponse } from '@/components/ai';
|
|
55
|
+
import { PromptInput } from '@/components/ai';
|
|
56
|
+
|
|
57
|
+
<Message role="assistant">
|
|
58
|
+
<MessageContent>
|
|
59
|
+
<MessageResponse isStreaming={isLoading}>
|
|
60
|
+
{streamingText}
|
|
61
|
+
</MessageResponse>
|
|
62
|
+
</MessageContent>
|
|
63
|
+
</Message>
|
|
64
|
+
<PromptInput onSubmit={sendMessage} isLoading={isLoading} />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Every component is composable with sub-components for full customization:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { CodeBlock, CodeBlockHeader, CodeBlockTitle, CodeBlockCopyButton, CodeBlockContent } from '@/components/ai';
|
|
71
|
+
|
|
72
|
+
<CodeBlock code={code} language="typescript">
|
|
73
|
+
<CodeBlockHeader>
|
|
74
|
+
<CodeBlockTitle>typescript</CodeBlockTitle>
|
|
75
|
+
<CodeBlockCopyButton />
|
|
76
|
+
</CodeBlockHeader>
|
|
77
|
+
<CodeBlockContent code={code} showLineNumbers />
|
|
78
|
+
</CodeBlock>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Stack
|
|
82
|
+
|
|
83
|
+
| Layer | Technology |
|
|
84
|
+
|---|---|
|
|
85
|
+
| **Framework** | Expo SDK 55, React Native 0.83, React 19 |
|
|
86
|
+
| **Styling** | Uniwind (Tailwind CSS for RN) |
|
|
87
|
+
| **Base UI** | React Native Reusables (shadcn/ui) |
|
|
88
|
+
| **Markdown** | react-native-enriched-markdown + react-native-streamdown |
|
|
89
|
+
| **Threading** | react-native-worklets 0.7 |
|
|
90
|
+
| **AI SDK** | Vercel AI SDK (`ai` + `@ai-sdk/react`) |
|
|
91
|
+
| **Animations** | react-native-reanimated 4.3 |
|
|
92
|
+
| **Icons** | lucide-react-native |
|
|
93
|
+
|
|
94
|
+
## Project Structure
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
app/
|
|
98
|
+
_layout.tsx # Drawer sidebar layout
|
|
99
|
+
index.tsx # Home screen with component grid
|
|
100
|
+
chat.tsx # Full chat demo
|
|
101
|
+
[slug].tsx # Dynamic component preview route
|
|
102
|
+
components/
|
|
103
|
+
ai/ # AI chat components (the library)
|
|
104
|
+
ui/ # Base UI components (Reusables)
|
|
105
|
+
showcase/ # Sidebar + preview wrappers
|
|
106
|
+
demos/ # Interactive demos for each component
|
|
107
|
+
lib/
|
|
108
|
+
fonts.ts # Platform monospace font config
|
|
109
|
+
component-registry.ts # Component catalog for sidebar nav
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Known Limitations
|
|
113
|
+
|
|
114
|
+
- **Streaming jank**: `EnrichedMarkdownText` recalculates native layout on every prop change. Updates are throttled to ~80ms to mitigate. The proper fix (`react-native-streamdown` with worklet-based processing) requires `react-native-worklets` bundle mode which needs additional metro configuration. See [worklets bundle mode docs](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/).
|
|
115
|
+
- **LaTeX block math** (`$$...$$`) requires `flavor="github"` on `EnrichedMarkdownText`.
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "expo-ai-elements",
|
|
3
|
+
"main": "expo-router/entry",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "expo start -c",
|
|
7
|
+
"android": "expo start -c --android",
|
|
8
|
+
"ios": "expo start -c --ios",
|
|
9
|
+
"web": "expo start -c --web",
|
|
10
|
+
"clean": "rm -rf .expo node_modules",
|
|
11
|
+
"postinstall": "node scripts/apply-patches.js",
|
|
12
|
+
"prepare": "husky",
|
|
13
|
+
"release": "standard-version",
|
|
14
|
+
"release:minor": "standard-version --release-as minor",
|
|
15
|
+
"release:major": "standard-version --release-as major",
|
|
16
|
+
"release:patch": "standard-version --release-as patch",
|
|
17
|
+
"release:dry": "standard-version --dry-run"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@ai-sdk/react": "^3.0.144",
|
|
21
|
+
"@react-navigation/drawer": "^7.9.4",
|
|
22
|
+
"@react-navigation/native": "^7.0.0",
|
|
23
|
+
"@rn-primitives/accordion": "^1.4.0",
|
|
24
|
+
"@rn-primitives/alert-dialog": "^1.4.0",
|
|
25
|
+
"@rn-primitives/aspect-ratio": "^1.4.0",
|
|
26
|
+
"@rn-primitives/avatar": "^1.4.0",
|
|
27
|
+
"@rn-primitives/checkbox": "^1.4.0",
|
|
28
|
+
"@rn-primitives/collapsible": "^1.4.0",
|
|
29
|
+
"@rn-primitives/context-menu": "^1.4.0",
|
|
30
|
+
"@rn-primitives/dialog": "^1.4.0",
|
|
31
|
+
"@rn-primitives/dropdown-menu": "^1.4.0",
|
|
32
|
+
"@rn-primitives/hover-card": "^1.4.0",
|
|
33
|
+
"@rn-primitives/label": "^1.4.0",
|
|
34
|
+
"@rn-primitives/menubar": "^1.4.0",
|
|
35
|
+
"@rn-primitives/popover": "^1.4.0",
|
|
36
|
+
"@rn-primitives/portal": "~1.4.0",
|
|
37
|
+
"@rn-primitives/progress": "^1.4.0",
|
|
38
|
+
"@rn-primitives/radio-group": "^1.4.0",
|
|
39
|
+
"@rn-primitives/select": "^1.4.0",
|
|
40
|
+
"@rn-primitives/separator": "^1.4.0",
|
|
41
|
+
"@rn-primitives/slot": "^1.4.0",
|
|
42
|
+
"@rn-primitives/switch": "^1.4.0",
|
|
43
|
+
"@rn-primitives/tabs": "^1.4.0",
|
|
44
|
+
"@rn-primitives/toggle": "^1.4.0",
|
|
45
|
+
"@rn-primitives/toggle-group": "^1.4.0",
|
|
46
|
+
"@rn-primitives/tooltip": "^1.4.0",
|
|
47
|
+
"ai": "^6.0.142",
|
|
48
|
+
"class-variance-authority": "^0.7.1",
|
|
49
|
+
"clsx": "^2.1.1",
|
|
50
|
+
"expo": "~55.0.11",
|
|
51
|
+
"expo-clipboard": "~55.0.11",
|
|
52
|
+
"expo-constants": "~55.0.11",
|
|
53
|
+
"expo-dev-client": "~55.0.22",
|
|
54
|
+
"expo-haptics": "~55.0.11",
|
|
55
|
+
"expo-linking": "~55.0.11",
|
|
56
|
+
"expo-router": "~55.0.10",
|
|
57
|
+
"expo-splash-screen": "~55.0.15",
|
|
58
|
+
"expo-status-bar": "~55.0.5",
|
|
59
|
+
"expo-system-ui": "~55.0.13",
|
|
60
|
+
"expo-updates": "~55.0.18",
|
|
61
|
+
"lucide-react-native": "^0.545.0",
|
|
62
|
+
"react": "19.2.0",
|
|
63
|
+
"react-dom": "19.2.0",
|
|
64
|
+
"react-native": "0.83.4",
|
|
65
|
+
"react-native-drawer-layout": "^4.2.2",
|
|
66
|
+
"react-native-enriched-markdown": "^0.4.1",
|
|
67
|
+
"react-native-gesture-handler": "~2.30.0",
|
|
68
|
+
"react-native-keyboard-controller": "1.20.7",
|
|
69
|
+
"react-native-reanimated": "4.2.1",
|
|
70
|
+
"react-native-safe-area-context": "~5.6.0",
|
|
71
|
+
"react-native-screens": "~4.23.0",
|
|
72
|
+
"react-native-streamdown": "^0.1.1",
|
|
73
|
+
"react-native-svg": "15.15.3",
|
|
74
|
+
"react-native-web": "^0.21.0",
|
|
75
|
+
"react-native-webview": "13.16.0",
|
|
76
|
+
"react-native-worklets": "0.7.2",
|
|
77
|
+
"remend": "1.2.2",
|
|
78
|
+
"tailwind-merge": "^3.5.0",
|
|
79
|
+
"tailwindcss": "^4.2.1",
|
|
80
|
+
"tailwindcss-animate": "^1.0.7",
|
|
81
|
+
"tw-animate-css": "^1.4.0",
|
|
82
|
+
"uniwind": "^1.5.0"
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@babel/core": "^7.26.0",
|
|
86
|
+
"@commitlint/cli": "^20.5.0",
|
|
87
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
88
|
+
"@types/react": "~19.2.10",
|
|
89
|
+
"husky": "^9.1.7",
|
|
90
|
+
"patch-package": "^8.0.1",
|
|
91
|
+
"prettier": "^3.6.2",
|
|
92
|
+
"prettier-plugin-tailwindcss": "^0.6.14",
|
|
93
|
+
"standard-version": "^9.5.0",
|
|
94
|
+
"typescript": "~5.9.2"
|
|
95
|
+
},
|
|
96
|
+
"publishConfig": {
|
|
97
|
+
"access": "public"
|
|
98
|
+
},
|
|
99
|
+
"files": [
|
|
100
|
+
"src/",
|
|
101
|
+
"README.md",
|
|
102
|
+
"LICENSE"
|
|
103
|
+
],
|
|
104
|
+
"repository": {
|
|
105
|
+
"type": "git",
|
|
106
|
+
"url": "git+https://github.com/muratcakmak/expo-ai-elements.git"
|
|
107
|
+
},
|
|
108
|
+
"bugs": {
|
|
109
|
+
"url": "https://github.com/muratcakmak/expo-ai-elements/issues"
|
|
110
|
+
},
|
|
111
|
+
"homepage": "https://github.com/muratcakmak/expo-ai-elements#readme"
|
|
112
|
+
}
|