Getting Started
This guide will help you set up @joe111/neo-ui in your React Native project and start building beautiful, modern mobile applications.
Prerequisites
Before you begin, make sure you have:
- Node.js (version 16 or higher)
- React Native development environment set up
- Expo CLI (if using Expo)
- TypeScript knowledge (recommended)
Installation
Using npm
npm install @joe111/neo-ui
Using yarn
yarn add @joe111/neo-ui
Using pnpm
pnpm add @joe111/neo-ui
Peer Dependencies
@joe111/neo-ui requires the following peer dependencies:
npm install react react-native @react-navigation/native @react-navigation/bottom-tabs @react-navigation/elements react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-screens react-native-svg
Or with yarn:
yarn add react react-native @react-navigation/native @react-navigation/bottom-tabs @react-navigation/elements react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-screens react-native-svg
Basic Setup
1. Theme Provider Setup
Wrap your entire application with the ThemeProvider
to enable theming:
// App.tsx (for standard React Native)
import React from "react";
import { ThemeProvider } from "@joe111/neo-ui";
import { MainNavigator } from "./src/navigation/MainNavigator";
export default function App() {
return (
<ThemeProvider>
<MainNavigator />
</ThemeProvider>
);
}
For Expo Router projects:
// app/_layout.tsx
import React from "react";
import { Stack } from "expo-router";
import { ThemeProvider } from "@joe111/neo-ui";
export default function RootLayout() {
return (
<ThemeProvider>
<Stack screenOptions={{ headerShown: false }} />
</ThemeProvider>
);
}
2. Your First Screen
Create your first screen using @joe111/neo-ui components:
// app/index.tsx (Expo Router) or src/screens/HomeScreen.tsx
import React, { useState } from "react";
import { View, Alert } from "react-native";
import { Box, Button, TextField, Typography } from "@joe111/neo-ui";
export default function HomeScreen() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = () => {
if (name && email) {
Alert.alert("Success", `Hello ${name}! We'll contact you at ${email}`);
} else {
Alert.alert("Error", "Please fill in all fields");
}
};
return (
<Box padding="lg" style={{ flex: 1, justifyContent: "center" }}>
<Typography
variant="h1"
style={{ textAlign: "center", marginBottom: 24 }}
>
Welcome to Neo UI
</Typography>
<TextField
label="Full Name"
placeholder="Enter your name"
value={name}
onChangeText={setName}
style={{ marginBottom: 16 }}
/>
<TextField
label="Email Address"
placeholder="Enter your email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
style={{ marginBottom: 24 }}
/>
<Button
variant="primary"
onPress={handleSubmit}
style={{ marginBottom: 12 }}
>
Get Started
</Button>
<Button
variant="outline"
onPress={() => Alert.alert("Info", "Learn more about Neo UI")}
>
Learn More
</Button>
</Box>
);
}
Import Strategies
@joe111/neo-ui supports two import strategies:
Individual Imports (Recommended for Tree Shaking)
import React from "react";
import { Button } from "@joe111/neo-ui/Button";
import { Typography } from "@joe111/neo-ui/Typography";
import { Box } from "@joe111/neo-ui/Box";
Barrel Imports (Convenient)
import React from "react";
import { Button, Typography, Box } from "@joe111/neo-ui";
Available Components
Layout Components
- Box - Flexible container with theme-aware spacing and styling
- ThemedView - View component with automatic theme integration
- ParallaxScrollView - Smooth scrolling with parallax effects
Form Components
- Button - Customizable button with multiple variants
- TextField - Input field with validation and theming
- Chip - Compact elements for tags, filters, or actions
Typography
- Typography - Text component with predefined styles and variants
- ThemedText - Text component that adapts to theme changes
Data Display
- Avatar - User profile pictures with fallbacks and group support
- Badge - Small status indicators with customizable colors
- Rating - Interactive star rating component
- Ticker - Animated text ticker for scrolling content
Feedback
- Alert - Alert messages with different severity levels
- Toast - Global toast notifications with state management
- Skeleton - Loading placeholders with shimmer effects
Project Structure
Here's a recommended project structure when using @joe111/neo-ui:
your-app/
├── app/ # Expo Router pages (if using Expo Router)
│ ├── _layout.tsx
│ ├── index.tsx
│ └── (tabs)/
├── src/
│ ├── components/ # Custom components
│ │ ├── CustomCard.tsx
│ │ └── UserProfile.tsx
│ ├── screens/ # Screen components (if not using Expo Router)
│ │ ├── HomeScreen.tsx
│ │ └── ProfileScreen.tsx
│ ├── navigation/ # Navigation setup (if not using Expo Router)
│ │ └── MainNavigator.tsx
│ ├── hooks/ # Custom hooks
│ │ └── useAuth.ts
│ ├── utils/ # Utility functions
│ │ └── validation.ts
│ └── types/ # TypeScript type definitions
│ └── index.ts
├── package.json
└── tsconfig.json
TypeScript Configuration
If you're using TypeScript (recommended), make sure your tsconfig.json
includes:
{
"compilerOptions": {
"target": "es2017",
"lib": ["es2017", "es2018", "es6"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src/**/*", "app/**/*", "App.tsx"],
"exclude": ["node_modules"]
}
Environment Setup
Expo Projects
If you're using Expo, add these dependencies to your package.json
:
{
"dependencies": {
"expo": "~49.0.0",
"expo-router": "^2.0.0",
"expo-status-bar": "~1.6.0",
"react": "19.0.0",
"react-native": "0.79.3",
"@joe111/neo-ui": "^1.3.11",
"@expo/vector-icons": "^14.1.0",
"@react-navigation/native": "^7.1.6",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/elements": "^2.3.8",
"react-native-gesture-handler": "~2.24.0",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.10.0",
"react-native-svg": "^15.12.0"
}
}
React Native CLI Projects
For React Native CLI projects, ensure you have:
{
"dependencies": {
"react": "19.0.0",
"react-native": "0.79.3",
"@joe111/neo-ui": "^1.3.11",
"@react-navigation/native": "^7.1.6",
"@react-navigation/bottom-tabs": "^7.3.10",
"@react-navigation/elements": "^2.3.8",
"react-native-gesture-handler": "~2.24.0",
"react-native-reanimated": "~3.17.4",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.10.0",
"react-native-svg": "^15.12.0"
}
}
Custom Theming
Creating a Custom Theme
// src/theme/customTheme.ts
import { createTheme } from "@joe111/neo-ui";
export const customTheme = createTheme({
colors: {
primary: "#007AFF",
secondary: "#5856D6",
success: "#34C759",
warning: "#FF9500",
error: "#FF3B30",
// ... other colors
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
},
typography: {
h1: {
fontSize: 32,
fontWeight: "bold",
},
h2: {
fontSize: 24,
fontWeight: "600",
},
// ... other typography styles
},
});
Using Custom Theme
// App.tsx
import React from "react";
import { ThemeProvider } from "@joe111/neo-ui";
import { customTheme } from "./src/theme/customTheme";
import { YourApp } from "./YourApp";
export default function App() {
return (
<ThemeProvider theme={customTheme}>
<YourApp />
</ThemeProvider>
);
}
Common Patterns
Creating Custom Components
Extend Neo UI components to create your own:
// src/components/CustomCard.tsx
import React from "react";
import { StyleSheet } from "react-native";
import { Box, Typography, Button, useTheme } from "@joe111/neo-ui";
interface CustomCardProps {
title: string;
description: string;
onPress?: () => void;
children?: React.ReactNode;
}
export function CustomCard({
title,
description,
onPress,
children,
}: CustomCardProps) {
const theme = useTheme();
const styles = StyleSheet.create({
container: {
backgroundColor: theme.colors.card,
borderRadius: 12,
shadowColor: theme.colors.shadow,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
});
return (
<Box padding="lg" style={styles.container}>
<Typography variant="h3" style={{ marginBottom: 8 }}>
{title}
</Typography>
<Typography variant="body1" style={{ marginBottom: 12 }}>
{description}
</Typography>
{children}
{onPress && (
<Button variant="outline" size="sm" onPress={onPress}>
Learn More
</Button>
)}
</Box>
);
}
Form with Validation
// src/components/ContactForm.tsx
import React, { useState } from "react";
import { Alert } from "react-native";
import { Box, TextField, Button, Typography } from "@joe111/neo-ui";
interface FormData {
name: string;
email: string;
message: string;
}
interface FormErrors {
name?: string;
email?: string;
message?: string;
}
export function ContactForm() {
const [formData, setFormData] = useState<FormData>({
name: "",
email: "",
message: "",
});
const [errors, setErrors] = useState<FormErrors>({});
const [loading, setLoading] = useState(false);
const validateForm = (): boolean => {
const newErrors: FormErrors = {};
if (!formData.name.trim()) {
newErrors.name = "Name is required";
}
if (!formData.email.trim()) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
newErrors.email = "Please enter a valid email";
}
if (!formData.message.trim()) {
newErrors.message = "Message is required";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async () => {
if (!validateForm()) return;
setLoading(true);
try {
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 2000));
Alert.alert("Success", "Your message has been sent!");
setFormData({ name: "", email: "", message: "" });
} catch (error) {
Alert.alert("Error", "Failed to send message. Please try again.");
} finally {
setLoading(false);
}
};
return (
<Box padding="lg">
<Typography variant="h2" style={{ marginBottom: 24 }}>
Contact Us
</Typography>
<TextField
label="Name"
placeholder="Your full name"
value={formData.name}
onChangeText={(text) => setFormData({ ...formData, name: text })}
error={!!errors.name}
errorText={errors.name}
style={{ marginBottom: 16 }}
/>
<TextField
label="Email"
placeholder="your@email.com"
value={formData.email}
onChangeText={(text) => setFormData({ ...formData, email: text })}
error={!!errors.email}
errorText={errors.email}
keyboardType="email-address"
autoCapitalize="none"
style={{ marginBottom: 16 }}
/>
<TextField
label="Message"
placeholder="Your message"
value={formData.message}
onChangeText={(text) => setFormData({ ...formData, message: text })}
error={!!errors.message}
errorText={errors.message}
multiline
numberOfLines={4}
style={{ marginBottom: 24 }}
/>
<Button
variant="primary"
onPress={handleSubmit}
loading={loading}
disabled={loading}
>
{loading ? "Sending..." : "Send Message"}
</Button>
</Box>
);
}
Using Hooks
Theme Hook
import { useTheme } from "@joe111/neo-ui";
export function MyComponent() {
const theme = useTheme();
return (
<View style={{ backgroundColor: theme.colors.background }}>
<Text style={{ color: theme.colors.text }}>Themed Component</Text>
</View>
);
}
Next Steps
Now that you have @joe111/neo-ui set up, explore:
- Theming - Learn about customizing themes
- Components - Explore all available components
- Navigation - Navigation patterns and best practices
- Customization - Advanced customization techniques
Resources
- Demo App - Try out components in our interactive demo
- GitHub Repository - Source code and examples
- NPM Package - Package details and versions
- Issues - Report bugs and request features
Ready to build beautiful React Native applications with Neo UI? Let's get started!