@rootnative/cli
v0.0.0-alpha.14
Published
CLI for adding RootNative UI components to your React Native project
Maintainers
Readme
rootnative
CLI for adding RootNative UI components directly into your React Native or Expo project. Inspired by shadcn/ui — you own the code.
Quick start
Start a new project:
npx rootnative create my-appOr add components to an existing project:
npx rootnative init
npx rootnative add button cardHow it works
Instead of installing components as an npm package, the CLI copies the source files into your project. You get full ownership — customize styles, adjust behavior, or remove what you don't need.
The theme system (@rootnative/core) stays as an npm dependency so theme updates propagate automatically.
Requirements
- Node.js >= 18
- React Native >= 0.72 or Expo SDK >= 49
- TypeScript project (recommended)
Commands
rootnative create [name]
Scaffold a new Expo project with RootNative UI pre-configured (ThemeProvider wired up, example components included).
npx rootnative create my-appIt prompts for project name, display name, template, and package manager.
Options:
| Flag | Description |
|------|-------------|
| -y, --yes | Skip prompts and use defaults |
| -t, --template <name> | Template to use (blank, with-router) |
| --package-manager <pm> | Package manager to use (npm, yarn, pnpm, bun) |
Non-interactive mode for CI/automation:
npx rootnative create my-app -y --template with-router --package-manager pnpmrootnative init
Initialize your project for RootNative UI.
npx rootnative initThis will:
- Detect your project type (Expo or bare React Native)
- Detect your package manager (npm, yarn, pnpm, bun)
- Detect path aliases from your
tsconfig.json - Prompt for component and utility output directories
- Create an
rootnative.jsonconfig file - Offer to add the LLM-docs pointer to your project's
CLAUDE.md - Offer to install
@rootnative/core
Steps 6 and 7 are confirmation prompts; -y accepts both.
Options:
| Flag | Description |
|------|-------------|
| -y, --yes | Skip all prompts and use detected defaults |
| --components-alias <alias> | Components install path (default: @/components/ui) |
| --lib-alias <alias> | Utility files path (default: @/lib) |
| --package-manager <pm> | Package manager to use (npm, yarn, pnpm, bun) |
Non-interactive mode for CI/automation:
# Accept all defaults
npx rootnative init -y
# With custom paths
npx rootnative init -y --components-alias "~/ui" --lib-alias "~/utils"rootnative add <components...>
Add one or more components to your project.
npx rootnative add button
npx rootnative add card chip text-field
npx rootnative add appbar # auto-adds button + icon-button + typography dependenciesOptions:
| Flag | Description |
|------|-------------|
| -f, --force | Overwrite existing components |
| -d, --dry-run | Preview what would be installed without writing files |
| --package-manager <pm> | Package manager to use (npm, yarn, pnpm, bun) |
The add command:
- Resolves the full dependency graph (e.g.
appbarrequiresbutton,icon-buttonandtypography) - Shows a plan of components, utilities, and npm packages to install
- Copies component files with import paths rewritten to match your project
- Generates a utility barrel file (
rootnative-utils.ts) - Installs required npm dependencies
rootnative update [components...]
Update installed components to the latest version from the registry.
npx rootnative update button # update specific components
npx rootnative update --all # update everything installed
npx rootnative update --all --dry-run # preview the diff firstOptions:
| Flag | Description |
|------|-------------|
| -a, --all | Update all installed components |
| -d, --dry-run | Show diff without applying changes |
Local modifications are detected by diffing against the registry source — review the diff with --dry-run before applying if you've customized component files.
rootnative upgrade
Upgrade @rootnative/core to the latest published version and install any new peer dependencies.
npx rootnative upgradeOptions:
| Flag | Description |
|------|-------------|
| -y, --yes | Skip confirmation prompt |
| -a, --all | Also update all installed component files |
| --package-manager <pm> | Package manager to use (npm, yarn, pnpm, bun) |
The upgrade command:
- Detects the installed
@rootnative/coreversion fromnode_modules - Fetches the latest version from the npm registry
- Compares peer dependencies between the installed and latest versions
- Shows a plan with the version bump, new required peer deps, changed ranges, and removed deps
- Upgrades
@rootnative/coreand installs any new required peer dependencies - Reports optional peer deps that aren't installed (does not auto-install them)
- Lists peer deps that are no longer required so you can remove them manually
- Moves
registryVersioninrootnative.jsonforward to the new release tag, so subsequentadd/updatecalls fetch matching sources - With
-a, --all, also updates the installed component files
Non-interactive mode for CI/automation:
npx rootnative upgrade -yrootnative list
Show all available components with their install status.
npx rootnative listrootnative doctor
Check your project for common issues.
npx rootnative doctorChecks include:
rootnative.jsonexists and is valid@rootnative/coreis installed- React Native version compatibility
- Installed component file integrity
@rootnative/inertia— a hard failure when missing, since every animated component needs it- Optional peer dependencies (
react-native-safe-area-context,@expo/vector-icons) — reported as warnings
Configuration
rootnative init creates an rootnative.json in your project root:
{
"$schema": "https://rootnative.github.io/ui/schema.json",
"aliases": {
"components": "@/components/ui",
"lib": "@/lib"
},
"registryUrl": "https://raw.githubusercontent.com/rootnative/ui",
"registryVersion": "v0.0.0-alpha.4"
}| Field | Description |
|-------|-------------|
| aliases.components | Where component directories are created |
| aliases.lib | Where utility files are placed |
| registryUrl | Base URL for fetching component source files |
| registryVersion | Git ref to fetch from (branch, tag, or commit). init pins this to the v<version> tag of the latest published release, falling back to main only when npm is unreachable or the tag isn't pushed yet. upgrade moves the pin forward |
Output structure
After running npx rootnative add button appbar:
src/
components/
ui/
button/
Button.tsx
types.ts
styles.ts
index.ts
elevationShadow.ts # shared internal, flattened per component
usePressMorph.ts
useStateLayer.ts
icon-button/ # auto-added (appbar dependency)
IconButton.tsx
types.ts
styles.ts
index.ts
useBooleanProgress.ts
usePressMorph.ts
useStateLayer.ts
typography/ # auto-added (appbar dependency)
Typography.tsx
types.ts
styles.ts
index.ts
appbar/
AppBar.tsx
types.ts
styles.ts
index.ts
safe-area.tsx
lib/
color.ts
elevation.ts
pressable.ts
render-icon.tsx
rtl.ts
rootnative-utils.ts # generated barrelShared internal hooks (useStateLayer, usePressMorph, …) are copied into
each component directory that uses them rather than into a shared folder, so
each installed component stays self-contained.
Available components
| Component | Description |
|-----------|-------------|
| typography | Text component with 15 MD3 type scale variants |
| button | 5 variants (filled, elevated, outlined, text, tonal) with icon support |
| button-group | Standard and connected button groups with single or multi-select toggle behavior |
| icon-button | 4 variants (filled, tonal, outlined, standard) with toggle support |
| fab | Floating action button with 4 color variants, 3 sizes, and optional extended label |
| appbar | Top app bar with 4 variants and SafeAreaView support |
| avatar | Circular avatar with image, icon, or text initials and 5 sizes |
| card | 3 variants (elevated, filled, outlined) with optional press handler |
| chip | 4 variants (assist, filter, input, suggestion) with icon/avatar support |
| checkbox | Binary selection control |
| radio | Single-choice selection control |
| switch | Toggle control with optional icons |
| slider | Single-thumb or range slider with continuous and discrete modes |
| progress | Linear and circular progress indicators (determinate and indeterminate) |
| text-field | Text input with animated floating label, 2 variants (filled, outlined) |
| layout | Layout primitives: Box, Row, Column, Grid with responsive columns and spanning cells, and SafeAreaView wrapper |
| list | List container with interactive items and dividers |
| divider | Horizontal or vertical 1dp rule with optional leading/trailing insets and thickness/color overrides. |
| loading-indicator | MD3 Expressive shape-morphing loading spinner (contained + uncontained, determinate + indeterminate) |
| portal | Render children into a host elsewhere in the tree (overlays, dialogs, sheets) |
| dialog | Basic and full-screen modal dialogs with Icon / Title / Content / Actions slots, scrim, and Android back handling. |
| snackbar | Imperative snackbar queue — SnackbarProvider plus useSnackbar() with actions, durations, and safe-area aware placement. |
| menu | Anchored dropdown menu (Menu + Menu.Item) that flips and shifts to stay on screen, with self-managing or controlled visibility. |
| tooltip | Plain and rich tooltips anchored to a control, shown on hover or a long press |
| bottom-sheet | MD3 bottom sheet — modal (scrim) and standard variants, drag handle, velocity-based snap points, drag-to-dismiss. |
| tabs | Primary and secondary tab rows, fixed or scrollable, with a sliding active indicator |
| navigation-bar | MD3 navigation bar — 80dp bottom destination bar with an animated indicator pill |
| keyboard-avoiding-wrapper | Zero-config keyboard-aware wrapper for form layouts |
Import rewriting
The CLI rewrites imports so copied files work in your project:
| Original (library source) | Rewritten to |
|---------------------------|-------------|
| @rootnative/core | Unchanged (npm package) |
| @rootnative/utils | @/lib/rootnative-utils (local barrel) |
| ../icon-button | @/components/ui/icon-button (alias path) |
| ./styles | Unchanged (same directory) |
Usage after adding components
import { ThemeProvider } from '@rootnative/core'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
export default function App() {
return (
<ThemeProvider>
<Card>
<Button variant="filled" onPress={() => {}}>
Press me
</Button>
</Card>
</ThemeProvider>
)
}Docs
Full docs: https://rootnative.github.io/ui/cli
LLM-optimized reference: https://rootnative.github.io/ui/llms-full.txt — or read node_modules/@rootnative/cli/llms.txt for the exact installed version.
License
MIT
