shadcn for React Native: What Exists Today (Reusables, HeroUI Native, gluestack, 2026)

Is there shadcn for React Native? React Native Reusables, HeroUI Native and gluestack-ui v5 compared, with setup code and the NativeWind vs Uniwind choice.

shadcn for React Native: What Exists Today (Reusables, HeroUI Native, gluestack, 2026)

Every React web developer who moves to mobile asks the same question in their first week: where is shadcn? On the web you run one command, the component source lands in components/ui, and you own it. Then you open a React Native project and discover that npx shadcn add button produces a file full of div, Radix and CSS that no native renderer understands. There is no official shadcn React Native port. There is, however, a small set of projects that get you most of the way, and one of them is close enough that the difference rarely matters.

This guide covers what actually exists in late 2026, how each option works, and which one I would pick for a new app. Versions were checked on npm on October 26, 2026: @react-native-reusables/cli 0.7.1, @rn-primitives/* 1.5.x, heroui-native 1.0.11, @gluestack-ui/core 5.0.15, nativewind 4.2.7 (5.0.0-rc.0 in preview), uniwind 1.13.0, tamagui 3.1.4, tailwindcss 4.3.3. React Native 0.88 and Expo SDK 58 are current.

Why shadcn/ui does not just work in React Native

shadcn/ui is three things glued together: Radix UI primitives for behaviour and accessibility, Tailwind classes for styling, and a CLI that copies source instead of installing a package. None of the three ports directly.

  • Radix needs the DOM. Focus management, portals, pointer events and aria-* attributes are all DOM APIs. React Native has View, Pressable and an accessibility API with different prop names.
  • Tailwind needs CSS. React Native styles are JavaScript objects. A Tailwind class only works if something compiles it into a style object, which is the job of NativeWind or Uniwind.
  • No cascade, no data attributes. A Text inside a Button does not inherit the button’s text colour, and variants cannot hang off data-state="open". They have to be props or context.
  • No DOM portals. Dialogs, popovers and dropdown menus need an explicit portal host mounted near the root of the app.

So a real port has to replace Radix, pick a styling engine and work around the missing cascade. That is exactly what the first option does.

React Native Reusables: the closest thing to shadcn

React Native Reusables (founded-labs, MIT, about 8,700 GitHub stars) describes itself as bringing shadcn/ui to React Native, and it means it literally. It follows the shadcn new-york style, uses the same component names and file layout, and its CLI calls the shadcn CLI under the hood. Behaviour comes from RN Primitives, a universal port of Radix with an almost identical API. Styling is Tailwind classes through either NativeWind or Uniwind; you choose, and the CLI detects which one you have.

Start a new Expo project from a template:

# Nativewind template
npx @react-native-reusables/cli@latest init

# or the Uniwind template
npx @react-native-reusables/cli@latest init -t minimal-uniwind

Add components to an existing project:

npx @react-native-reusables/cli@latest add button card dialog
npx @react-native-reusables/cli@latest add --all      # everything
npx @react-native-reusables/cli@latest doctor         # check the setup

The files land in components/ui, exactly like on the web. The component list covers the shadcn core: accordion, alert, alert dialog, aspect ratio, avatar, badge, button, card, checkbox, collapsible, context menu, dialog, dropdown menu, hover card, input, label, menubar, popover, progress, radio group, select, separator, skeleton, switch, tabs, text, textarea, toggle, toggle group and tooltip. There are also blocks, including sponsored authentication screens from Clerk.

Using a component looks almost the same as shadcn, with one native detail:

import { Button } from '@/components/ui/button';
import { Text } from '@/components/ui/text';
import { Icon } from '@/components/ui/icon';
import { Save } from 'lucide-react-native';

export function SaveButton({ onPress }: { onPress: () => void }) {
  return (
    <Button variant="outline" onPress={onPress}>
      <Icon as={Save} className="size-4" />
      <Text>Save</Text>
    </Button>
  );
}

The label is a Text, not a bare string, because there is no cascade. The button publishes its text classes through a TextClassContext and the Text component reads them. Icons go through an Icon wrapper so you do not have to wrap every Lucide icon for className support. Open button.tsx after you add it and you will see cva variants with Platform.select blocks for web-only hover and focus rings. It is your code, so change it.

Two setup steps people miss. First, overlays need a portal host in the root layout:

// app/_layout.tsx (Expo Router)
import { PortalHost } from '@rn-primitives/portal';
import { Stack } from 'expo-router';
import '../global.css';

export default function RootLayout() {
  return (
    <>
      <Stack />
      <PortalHost />
    </>
  );
}

Second, some components cannot be controlled with open and onOpenChange the way Radix allows, because the menu has to measure its trigger after layout. DropdownMenu is the usual surprise: you open and close it through a ref. If you are coming from our dropdowns and pickers comparison, this is the same layout problem from the other side.

The honest caveats: the CLI has not had a release since March 2026 (the registry and docs keep moving, and in September the project added its components to catalogs.dev for agent-driven installs), and the CLI only has about 3,800 weekly npm downloads. The underlying @rn-primitives packages are at roughly 450,000, because people copy components and never run the CLI again. That is the shadcn model working as designed, but it also means updates are yours to pull.

HeroUI Native: a package, not copy-paste

HeroUI Native is the React Native sibling of HeroUI (formerly NextUI), Apache 2.0, about 3,700 stars and roughly 147,000 weekly downloads, with 1.0.11 released on October 20. It is built on Tailwind v4 through Uniwind, and every slot of every component is restyleable, but it ships as an npm package. You get updates with npm update instead of re-copying files, and you give up editing the source in place.

Its peer list tells you what you are signing up for: React 19, React Native 0.81 or newer, Reanimated 4 with Worklets, Gesture Handler 2.28 or 3.x, Screens, Safe Area Context, SVG, expo-blur, @gorhom/bottom-sheet 5, tailwind-merge and tailwind-variants. The setup from the official example app:

/* global.css */
@import 'tailwindcss';
@import 'uniwind';
@import 'heroui-native/styles';

@source './node_modules/heroui-native/lib';
// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withUniwindConfig } = require('uniwind/metro');

module.exports = withUniwindConfig(getDefaultConfig(__dirname), {
  cssEntryFile: './global.css',
});
// app/_layout.tsx
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Slot } from 'expo-router';
import '../global.css';

export default function RootLayout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <HeroUINativeProvider>
        <Slot />
      </HeroUINativeProvider>
    </GestureHandlerRootView>
  );
}

Because the sheet components sit on @gorhom/bottom-sheet, our bottom sheet guide applies to HeroUI’s sheets too, including the v5 dynamic sizing default. HeroUI Native is the right pick if you want a polished design system with themes out of the box and do not want to own component code. It is not shadcn, and it does not pretend to be.

gluestack-ui v5: copy-paste with NativeWind v5

gluestack-ui from GeekyAnts has been copy-paste since v2, and v5 (June 2026) moved to NativeWind v5 on Tailwind v4 with Expo Router as the default target:

npx gluestack-ui init
npx gluestack-ui add button

The philosophy is the same as shadcn: components live in your repo. The API is not. gluestack has its own component vocabulary (ButtonText, ButtonIcon, compound parts) and its own theming tokens, so a shadcn snippet from a web project will not paste across. One thing to check before you commit: NativeWind v5 is still 5.0.0-rc.0 on npm (the latest tag is 4.2.7), so a gluestack v5 project runs on a release candidate styling engine today.

The styling engine decides more than the component library

Every Tailwind-flavoured option above sits on one of two engines, and that choice outlives the component library.

Engine Version (Oct 26, 2026) Tailwind Weekly downloads Notes
NativeWind 4.2.7 stable, 5.0.0-rc.0 v3 (4.x), v4 (5.x) ~1.28M The incumbent. v5 moves the core into react-native-css 3.0.7
Uniwind 1.13.0 v4 ~615K From the Unistyles author. 1.13 honours CSS cascade order on native

My read: for a new project in late 2026, Tailwind v4 is the target, which means Uniwind today or NativeWind once v5 leaves release candidate. React Native Reusables supports both, so it is the option that does not force the decision. If you do not want Tailwind at all, Unistyles 3.6 with plain StyleSheet objects is the fast alternative, and React Native Paper still wins if you want Material Design without thinking about it.

The non-shadcn alternatives worth knowing

Tamagui (3.1.4, about 124,000 weekly downloads) is a styling system plus optimizing compiler plus component kit, with its own token and theme model and first-class web output. It is excellent for universal apps and nothing like shadcn in feel. Pick it when the web build matters as much as the native one.

Expo UI (@expo/ui 58.0.23) goes the opposite way: real SwiftUI and Jetpack Compose components behind a React API. You get platform-native controls with zero styling effort and very little visual control. Good for settings screens and forms that should look like the OS; wrong for a branded design system. More on where it fits in our Expo explainer.

Comparison

Option Model shadcn API parity Styling License Best for
React Native Reusables Copy source (shadcn CLI) High: same names, new-york style, Radix-like primitives NativeWind or Uniwind MIT Teams who know shadcn and want to own the code
HeroUI Native npm package Low: own API Uniwind (Tailwind v4) Apache 2.0 A finished design system with themes
gluestack-ui v5 Copy source (own CLI) Medium: same model, different API NativeWind v5 MIT Teams already on gluestack or NativeWind v5
Tamagui npm package + compiler None Own tokens MIT Universal apps where web output matters
Expo UI npm package None Platform native MIT OS-native forms and settings

Common problems

  • Classes do nothing. The CSS entry file is not imported in the root layout, or Metro is not wrapped with the engine’s config. Run npx @react-native-reusables/cli@latest doctor for Reusables setups.
  • Dialog or popover never appears. No PortalHost mounted, or it is mounted inside a screen instead of the root.
  • Text ignores the variant colour. You passed a string instead of the library’s Text component, so the text context never applied.
  • Reanimated errors after install. Reanimated 4 needs react-native-worklets and the New Architecture. On Expo SDK 58 both are the default; on an older bare app, check the Reanimated version against your React Native version first.
  • Pasting web shadcn code. It will not compile. Copy from the React Native registry, not from ui.shadcn.com.

What I would pick

For a new Expo app with a team that already ships shadcn on the web: React Native Reusables on Uniwind. The names match, the code is yours, and the mental model carries over, which matters more than any single component. For a small team that wants a good-looking app this month and will never edit a button’s source: HeroUI Native. For everything else, stop and decide the styling engine first, because that is the dependency you will live with for years. If you are still choosing between web and native stacks altogether, our React vs React Native breakdown is the place to start.

FAQ

Is there an official shadcn/ui for React Native?

No. shadcn/ui targets the web. The closest port is React Native Reusables, which follows the shadcn new-york style, uses the shadcn CLI under the hood and replaces Radix with RN Primitives.

Can I use the shadcn CLI in a React Native project?

Yes, with a React Native registry. React Native Reusables publishes registries that work with npx shadcn@latest, and its own CLI is a thin wrapper that saves you the registry URLs.

Does shadcn for React Native need NativeWind?

It needs a Tailwind engine for native. React Native Reusables supports NativeWind and Uniwind; HeroUI Native uses Uniwind; gluestack-ui v5 uses NativeWind v5.

Does React Native Reusables work with Expo?

Yes. The init command scaffolds an Expo project, and the components work in Expo Router apps and on the web through React Native Web.

Is HeroUI Native the same as shadcn?

No. HeroUI Native is an installed package with its own API and themes. shadcn-style libraries copy component source into your project so you own and edit it.

Leave a Reply 0

Your email address will not be published. Required fields are marked *