Semantic design tokens · Tailwind v4 · Reanimated on the UI thread.
React Native for Expo, and now React on the web.
Documentation · Installation · Components · Web · Theming · CLI
PanelUI is an open-source React Native UI component library for Expo apps, styled with Tailwind CSS v4 and animated with Reanimated 4. 140 accessible, typed component modules — buttons, inputs, forms, dialogs, bottom sheets, charts, calendars, maps and a set of AI chat components — in one coherent visual language, with light and dark themes out of the box.
Pure TypeScript with no native modules, so it runs in Expo Go with no prebuild, no Xcode and
no Android Studio.
New: PanelUI for the web. panelui-web is a collection of eleven
components for React on the web, in the same visual language and drawn in your project's own
theme: a board of cards you drag, a canvas of nodes and edges, a globe, KPI cards and more.
Why PanelUI
- ⚡ Fast styling — Uniwind brings Tailwind v4 to React Native with no Babel transform, around 2.4–3× faster than the alternatives.
- 🧵 UI-thread animations — press feedback, switches, sheets, dialogs and tabs all run on the UI thread with Reanimated 4. No JS-thread jank.
- 🎨 Semantic design tokens — one colour system (
background,primary,muted,destructive, …) across light and dark, precomputed to static values for native. - 🌗 Native dark mode — theme switching is applied natively, without re-rendering your tree.
- ♿ Accessible by default — every interactive component wires up
accessibilityRoleand mirrors its state. - 🧩 Compound APIs —
Card.Header,Dialog.Content,Table.Rowcompose the way the markup reads. - 📦 Typed, tree-shakeable, zero native code — works in Expo Go, ships full TypeScript types.
Getting started
Needs Node 20+. A new app, with everything below already done:
npx create-panelui-app@latest
Adding it to an app you already have, on Expo SDK 57+:
npx expo install panelui-native npx expo install uniwind tailwindcss react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context react-native-svg @react-native-masked-view/masked-view expo-linear-gradient
Then three files — a Metro config, a CSS entry and the provider. The installation guide walks through each one and lists a fix for every error people hit.
Or copy the source
panelui-cli copies a component's source into your project, to own and edit:
npx panelui-cli@latest init npx panelui-cli@latest add button
Both approaches are supported and you can mix them. See the CLI docs.
Usage
import { Button, Card, Dialog, Input } from 'panelui-native'; function CreateProject() { return ( <Card> <Card.Header> <Card.Title>Create project</Card.Title> <Card.Description>Deploy your new project in one click.</Card.Description> </Card.Header> <Card.Content className="gap-4"> <Input label="Name" placeholder="My project" /> </Card.Content> <Card.Footer> <Dialog> <Dialog.Trigger> <Button>Deploy</Button> </Dialog.Trigger> <Dialog.Content> <Dialog.Title>Are you sure?</Dialog.Title> <Dialog.Description>This will start a deployment.</Dialog.Description> <Dialog.Footer> <Dialog.Close> <Button variant="ghost" size="sm">Cancel</Button> </Dialog.Close> <Dialog.Close> <Button size="sm">Confirm</Button> </Dialog.Close> </Dialog.Footer> </Dialog.Content> </Dialog> </Card.Footer> </Card> ); }
Every component takes className, so anything can be restyled with Tailwind classes:
<Button className="w-full rounded-full" labelClassName="uppercase"> Continue </Button>
Components
140 component modules, documented with live examples and full props tables at panelui.dev/docs.
- Layout & content — Card, Frame, PageHeader, Surface, Item, GridItem, Separator, Splitter, Typography, SplitView, Table, Timeline, Steps, Accordion, Collapsible, Carousel, EmptyState, Skeleton
- Forms & inputs — Form, Field, Input, Textarea, InputGroup, NumberInput, OtpInput, SearchBar, Select, Combobox, TagInput, Checkbox, RadioGroup, Switch, Slider, Rating, Signature, ColorPicker, DatePicker, TimePicker, DateTimePicker, Calendar, Label, MarkdownEditor, Questionnaire
- Actions & navigation — Button, ButtonGroup, ToggleButton, Fab, Menu, ContextMenu, Swipe, StackCard, SelectionMode, Sortable, Tabs, Breadcrumb, Pagination, SectionRail, Panelside, Tree, Chip, Badge
- Overlays & feedback — Dialog, BottomSheet, Drawer, Popover, Tooltip, Toast, Alert, Tour, Progress, Meter, Spinner, Loader
- Data visualisation — Plot, LineChart, LiveLineChart, AreaChart, MirrorAreaChart, BarChart, WaterfallChart, PyramidChart, ScatterChart, BubbleChart, BumpChart, CandlestickChart, PieChart, PolarAreaChart, FunnelChart, TreemapChart, SankeyChart, RingChart, RadarChart, HeatmapChart, HexChart, Kpi, Leaderboard, Countdown, Map, Marker, Flow, QRCode
- AI components — Message, MessageScroller, Response, Reasoning, Plan, Task, Sources, CodeBlock, Shimmer, ThinkingOrb, Soundwave
- Social — Post, ImageViewer, Compare, Avatar, Attachment
- Scroll & motion — ScrollHeader, ScrollFade, ScrollText, ScrollCanvas, TextAnimation, Marquee, Direction
Plus the primitives: PanelUIProvider, Portal, AnimatedPressable, useTheme, useThemeMode,
useToast, cn.
PanelUI for the web
panelui-web is a separate collection for React on the web: Next.js, Vite, React Router, or
anything else that runs React 18 or newer with Tailwind CSS v4. It is not a port of the components
above. It is eleven of its own, styled with Tailwind on the tokens a shadcn project already
defines, so they take your colours and radius in light and dark.
Copy a component's source into your project with the shadcn CLI. It lands in
components/panelui/ and is yours to edit:
npx shadcn@latest add https://panelui.dev/r/web/lane-board.json
Or install the package, and let Tailwind see the classes it uses:
npm install panelui-web
/* app/globals.css */ @import "tailwindcss"; @source "../node_modules/panelui-web/dist";
import { RollingNumber } from 'panelui-web/rolling-number'; <RollingNumber value={298} className="text-6xl font-bold" />
- Lane Board — lanes of cards, dragged with a pointer or carried with the keyboard
- Flow — a canvas of nodes joined by edges, to pan, zoom and rearrange
- Planet — the world as dots on a globe you can turn, with markers pinned to it
- Day Grid, Bar Picker, Range Meter, KPI, Rolling Number — figures, to read and to pick from
- Command Dock, Feedback, Tilt Card — asking, answering and showing
KPI and Flow have the same parts and props as the app library's, so a screen written for one reads the same in the other. Every component runs live in the docs, with its source under it, at panelui.dev/docs/web.
Theming
Six themes ship in theme.css — light, dark, moon,
moon-dark, grass and grass-dark. Each family sets its own radius scale as well as its own
palette, so switching one changes the shape of the UI too.
const { theme, setTheme } = useTheme(); setTheme('moon-dark'); setTheme('system'); // follow the device const { family, mode, setFamily, toggleMode } = useThemeMode(); toggleMode(); // dark ↔ light, staying in the current brand setFamily('grass'); // switch family, staying in the current mode
Tokens are CSS variables and can be overridden in your own global.css. See
Colors for the token reference and the
@variant shape overrides have to use, and Fonts
for pointing the library at a typeface of your own.
Coding agents
An agent writing React Native in your project has no idea PanelUI is there. It writes a styled
View where there is a Card, invents a prop Button does not have, and hardcodes #171717
into a screen that has six themes.
The skill tells it. In Claude Code it installs as a plugin, and brings the MCP server with it:
/plugin marketplace add panel-ui/PanelUI
/plugin install panelui
For any other agent — Cursor, Copilot, Windsurf, Codex — the same folder installs with the
skills CLI:
npx skills add panel-ui/PanelUI
It carries an index of every component and a file each with the anatomy, every prop with its type
and default, the variants and the parts, generated from the library's own TypeScript. Alongside
those: the install steps and every reason className silently does nothing, worked screens
for the compositions that come up (settings, form, chat, filters, charts, search), the hooks and
primitives, and the rules that are not negotiable. It reads from disk, so an agent with no network
tool is not left guessing.
The skill activates on its own once a project has panelui-native in its dependencies or a
panelui.json beside it. Full details, and the URLs everything is served from, at
panelui.dev/docs/skills.
The web collection has a skill of its own, generated the same way from its source:
npx skills add panel-ui/PanelUI --skill panelui-web
Its components are shadcn registry items, so the shadcn MCP server can search and add them once
the registry is named in components.json. Both are covered at
panelui.dev/docs/web/skills and
panelui.dev/docs/web/mcp.
Example app
An Expo Router showcase with a live demo for every component and a theme picker — used to smoke-test the whole library in all six themes before a release.
git clone https://github.com/panel-ui/PanelUI.git cd PanelUI npm install npx expo prebuild --clean # in apps/example, once npm run example
The showcase needs a development build; it does not run in Expo Go. One component is the
reason — Map, whose renderer is native code that Expo Go's prebuilt binary does not contain.
Opening it in Expo Go closes the app with nothing in the terminal, which looks like a crash in
the library and is not one. See apps/example/README.md.
The library itself is a different matter: it ships no native code and runs in Expo Go.
Contributing
Contributions are welcome. The library lives in packages/panelui, the
showcase in apps/example and the documentation site in
apps/docs.
npm install # install workspace deps npm test # run every repository contract test npm run typecheck # typecheck all workspaces npm run build # build the library
Read CONTRIBUTING.md before opening a pull request, and please follow the Code of Conduct.
Community
- Report a bug or request a component
- Ask a question in Discussions
- Star the repo if PanelUI is useful to you — it is how other people find it
Contributors
Thank you to everyone who has shipped something here. If you would like to join them, CONTRIBUTING.md is the place to start.
Issue reporters
A clear bug report is how most fixes here start. Thank you to everyone who took the time to open one.
License
MIT © Khalid Abdi