Skip to content

React Native

Build beautiful mobile applications with Galaxy UI components for React Native.

Overview

Galaxy UI for React Native provides 37 production-ready components styled with NativeWind v4 (Tailwind CSS for React Native). All components are fully typed with TypeScript and follow React Native best practices.

Prerequisites

Before you begin, make sure you have:

  • React Native 0.74+ (with New Architecture support)
  • Node.js 18+ or Bun 1.0+
  • NativeWind v4 configured
  • Expo 51+ or bare React Native project

Installation

Step 1: Initialize Galaxy UI

bash
# Using npx
npx @galaxy-stack/nebula-cli@latest init

# Using bunx
bunx @galaxy-stack/nebula-cli@latest init

The CLI will:

  1. ✅ Detect React Native automatically
  2. ✅ Install NativeWind v4 dependencies
  3. ✅ Create components.json configuration
  4. ✅ Set up utility functions
  5. ✅ Configure Tailwind CSS
  6. ✅ Export Button component with props: variant (6 options), size (4 options), onPress, disabled, children, className

Step 2: Add Components

bash
# Add a single component
npx @galaxy-stack/nebula-cli@latest add button

# Add multiple components
npx @galaxy-stack/nebula-cli@latest add button input dialog

Configuration

Galaxy UI creates a components.json file in your project root:

json
{
  "$schema": "https://galaxy-nebula.vercel.app/schema.json",
  "framework": "react-native",
  "typescript": true,
  "styling": "nativewind",
  "nativewind": {
    "version": "v4",
    "config": "tailwind.config.js"
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}

NativeWind v4 Setup

Make sure NativeWind v4 is properly configured:

babel.config.js

js
module.exports = function (api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      "nativewind/babel",
      "react-native-reanimated/plugin",
    ],
  };
};

tailwind.config.js

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.{js,jsx,ts,tsx}",
    "./app/**/*.{js,jsx,ts,tsx}",
    "./components/**/*.{js,jsx,ts,tsx}",
  ],
  presets: [require("nativewind/preset")],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        // ... more colors
      },
    },
  },
  plugins: [],
};

global.css

css
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  /* ... more variables */
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 210 40% 98%;
  --primary-foreground: 222.2 47.4% 11.2%;
  /* ... more variables */
}

Usage Examples

Button Component

tsx
import { Button } from '@/components/ui/button';
import { View } from 'react-native';

export default function App() {
  return (
    <View className="flex-1 items-center justify-center gap-4 p-4">
      {/* Default button */}
      <Button variant="default">Default Button</Button>

      {/* Secondary button */}
      <Button variant="secondary">Secondary Button</Button>

      {/* Outline button */}
      <Button variant="outline">Outline Button</Button>

      {/* With custom handler */}
      <Button onPress={() => console.log('Pressed!')}>Click Me</Button>
    </View>
  );
}

Input Component

tsx
import { Input } from '@/components/ui/input';
import { View, Text } from 'react-native';
import { useState } from 'react';

export default function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <View className="flex-1 p-4 gap-4">
      <View className="gap-2">
        <Text className="text-sm font-medium">Email</Text>
        <Input
          placeholder="Enter your email"
          value={email}
          onChangeText={setEmail}
          keyboardType="email-address"
          autoCapitalize="none"
        />
      </View>

      <View className="gap-2">
        <Text className="text-sm font-medium">Password</Text>
        <Input
          placeholder="Enter your password"
          value={password}
          onChangeText={setPassword}
          secureTextEntry
        />
      </View>
    </View>
  );
}

Dialog Component

tsx
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
  DialogClose,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';

export default function DialogExample() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button>Open Dialog</Button>
      </DialogTrigger>

      <DialogContent>
        <DialogHeader>
          <DialogTitle>Confirm Action</DialogTitle>
          <DialogDescription>
            Are you sure you want to continue? This action cannot be undone.
          </DialogDescription>
        </DialogHeader>

        <DialogFooter>
          <DialogClose asChild>
            <Button variant="outline">Cancel</Button>
          </DialogClose>
          <DialogClose asChild>
            <Button variant="default">Confirm</Button>
          </DialogClose>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

Available Components

Galaxy UI for React Native includes 37 mobile-optimized components:

Form & Input

  • Button
  • Input
  • Checkbox
  • Radio Group
  • Select
  • Slider
  • Switch
  • Textarea
  • Label

Layout

  • Separator
  • Accordion
  • Collapsible
  • Tabs
  • Aspect Ratio
  • Sheet
  • Toolbar
  • Navigation Menu
  • Pagination

Data Display

  • Avatar
  • Progress
  • Badge
  • Typography
  • Empty
  • Skeleton

Overlays

  • Dialog
  • Alert Dialog
  • Popover
  • Tooltip

Date & Time

  • Calendar
  • Calendar Range

Interactive

  • Toggle
  • Toggle Group

Dark Mode

Galaxy UI supports dark mode out of the box with NativeWind v4:

tsx
import { useColorScheme } from 'react-native';
import { StatusBar } from 'expo-status-bar';

export default function App() {
  const colorScheme = useColorScheme();

  return (
    <>
      <StatusBar style={colorScheme === 'dark' ? 'light' : 'dark'} />
      {/* Your app content */}
    </>
  );
}

TypeScript Support

All components are fully typed with TypeScript:

tsx
import type { ButtonProps } from '@/components/ui/button';

const CustomButton: React.FC<ButtonProps> = ({ children, ...props }) => {
  return (
    <Button {...props}>
      {children}
    </Button>
  );
};

Best Practices

1. Use Composition

tsx
import { Button } from '@/components/ui/button';
import { Spinner } from '@/components/ui/spinner';

function LoadingButton({ loading, children, ...props }) {
  return (
    <Button disabled={loading} {...props}>
      {loading && <Spinner size="sm" className="mr-2" />}
      {children}
    </Button>
  );
}

2. Customize with Tailwind

tsx
<Button className="bg-purple-600 active:bg-purple-700">
  Custom Button
</Button>

3. Handle Platform Differences

tsx
import { Platform } from 'react-native';

<Button
  className={Platform.select({
    ios: 'rounded-full',
    android: 'rounded-md',
  })}
>
  Platform Button
</Button>

Performance Tips

  1. Use useMemo for complex calculations
tsx
const filteredData = useMemo(() =>
  data.filter(item => item.active),
  [data]
);
  1. Use React.memo for expensive components
tsx
const MemoizedComponent = React.memo(MyComponent);
  1. Avoid inline functions in render
tsx
// ❌ Bad
<Button onPress={() => handlePress(id)}>

// ✅ Good
const handleButtonPress = useCallback(() => {
  handlePress(id);
}, [id]);

<Button onPress={handleButtonPress}>

Troubleshooting

NativeWind not working

Make sure you have:

  1. Installed NativeWind v4: npm install nativewind@^4.0.0
  2. Added nativewind/babel to babel.config.js
  3. Imported global.css in your App entry file

Components not styled correctly

Check that your tailwind.config.js includes the correct content paths:

js
content: [
  "./app/**/*.{js,jsx,ts,tsx}",
  "./components/**/*.{js,jsx,ts,tsx}",
],

Next Steps

Resources

Support

Having issues? Check our GitHub Issues or contact kevinbui210191@gmail.com

Released under the MIT License.