A comprehensive, modern UI component library for React Native and Expo applications
Hoddy UI is a versatile UI component and theming library that follows the Hoddy UI design guidelinesβa refined take on Material Design. Built with TypeScript, it provides a collection of reusable components, utilities, and a customizable theming system to simplify and accelerate mobile app development.
- π¨ Modern Design: Clean, Material Design-inspired components
- π Dark Mode: Built-in dark/light theme support with system preference detection
- π± Cross Platform: Works seamlessly with React Native and Expo
- π§ TypeScript: Full TypeScript support with comprehensive type definitions
- β‘ Performance: Optimized components with minimal bundle size
- π― Accessibility: ARIA-compliant and screen reader friendly
- π Extensible: Highly customizable with theming and configuration options
- π Responsive: Built-in responsive utilities and grid system
- π¬ Rich Animations: 7 built-in animation types with customizable timing and effects
Hoddy UI is organized as a monorepo with multiple packages:
| Package | Version | Description |
|---|---|---|
| @hoddy-ui/core | Main component library for React Native/Expo | |
| @hoddy-ui/next | Components optimized for Expo Router | |
| @hoddy-ui/utils | Utility functions and helpers |
Choose the package that best fits your project:
For standard React Native/Expo projects:
npm install @hoddy-ui/core
# or
yarn add @hoddy-ui/coreFor projects using Expo Router:
npm install @hoddy-ui/next
# or
yarn add @hoddy-ui/nextFor utility functions:
npm install @hoddy-ui/utils
# or
yarn add @hoddy-ui/utilsInstall the required peer dependencies:
npm install @expo/vector-icons @react-native-async-storage/async-storage @react-navigation/native expo-navigation-bar expo-system-ui react-native-safe-area-context react-native-size-matters react-native-reanimatedImportant: For react-native-reanimated, make sure to follow the installation guide for platform-specific setup as it requires additional configuration for iOS and Android.
- Wrap your app with the theme provider:
import React from "react";
import { UIThemeProvider, initialize } from "@hoddy-ui/core";
import App from "./App";
// Optional: Configure the library
initialize({
fontFamily: "YourCustomFont",
edgeToEdge: false, // Set to true for edge-to-edge display
colors: {
// Custom color overrides
primary: { main: "#6366f1" },
},
});
export default function Root() {
return (
<UIThemeProvider>
<App />
</UIThemeProvider>
);
}- Start using components:
import React, { useState } from "react";
import { View } from "react-native";
import {
Typography,
Button,
TextField,
OTPInput,
Animator,
} from "@hoddy-ui/core";
export default function HomeScreen() {
const [otp, setOtp] = useState("");
return (
<View style={{ padding: 20 }}>
<Animator type="fade" duration={1000}>
<Typography variant="h4" gutterBottom={20}>
Welcome to Hoddy UI!
</Typography>
</Animator>
<Animator type="slide" direction="up" delay={200}>
<TextField
label="Email"
variant="outlined"
keyboardType="email-address"
/>
</Animator>
<Animator type="slide" direction="up" delay={300}>
<OTPInput length={6} value={otp} onChange={setOtp} variant="outlined" />
</Animator>
<Animator type="grow" delay={400}>
<Button
title="Get Started"
variant="contained"
color="primary"
onPress={() => console.log("Button pressed!")}
/>
</Animator>
</View>
);
}Configure Hoddy UI globally using the initialize function:
import { initialize } from "@hoddy-ui/core";
initialize({
// Custom font family
fontFamily: "Inter-Regular",
// Google Maps API key for Locator component
googleMapApiKey: "your-api-key",
// Edge-to-edge display (affects Android navigation bar)
edgeToEdge: true,
// Custom color palette
colors: {
primary: {
main: "#6366f1",
light: "#818cf8",
dark: "#4f46e5",
},
secondary: {
main: "#ec4899",
light: "#f472b6",
dark: "#db2777",
},
},
});The theme system supports:
- Automatic: Follows system theme preference
- Light: Force light theme
- Dark: Force dark theme
Users can switch themes at runtime using the theme context.
SafeAreaView- Safe area wrapperGrid&GridItem- Flexible grid systemAdaptiveStatusBar- Theme-aware status bar
Typography- Comprehensive text component- Rich text support with multiple variants (h1-h6, body1, body2, caption)
TextField- Material Design text inputTextField2- Alternative text field variantOTPInput- One-Time Password input with auto-advance and paste supportFormWrapper- Form container with validationLocator- Location picker with Google Maps integration
Button- Primary action buttonIconButton- Icon-only buttonLinkButton- Text-based button
FlashMessage- Toast notificationsAlertX- Alert dialogsSpinner- Loading indicators
Avatar- User profile imagesList,ListItem,ListItemText- List components
Popup- Modal dialogs and sheets with lifecycle callbacks and smooth animations
Animator- Unified animation component with 7 animation types (fade, grow, slide, blink, float, roll, thrownup)- Built with react-native-reanimated for 60fps native performance
- Animation hooks - Direct access to animation logic (
useFadeAnimation,useSlideAnimation, etc.)
Hoddy UI includes a comprehensive animation system with a unified Animator component that provides 7 different animation types with consistent, easy-to-use props.
- Fade - Smooth fade in/out transitions
- Grow - Scale-based growth animations
- Slide - Directional slide animations (up, down, left, right)
- Blink - Continuous opacity blinking effects
- Float - Floating up/down motion with fade
- Roll - Combined rotation and translation effects
- Thrown Up - Spring-based upward animations
import { Animator } from "@hoddy-ui/core";
// Fade animation with auto-close
<Animator type="fade" duration={1000} closeAfter={3000}>
<Notification>This fades in and out after 3 seconds</Notification>
</Animator>
// Slide animation from bottom
<Animator type="slide" direction="up" duration={800}>
<Modal>This slides up from the bottom</Modal>
</Animator>
// Continuous blinking effect
<Animator type="blink" blinkDuration={1000} minOpacity={0.3}>
<Badge>This blinks continuously</Badge>
</Animator>
// Custom floating effect
<Animator type="float" floatDistance={20} floatDuration={2000}>
<FloatingButton>This floats up and down</FloatingButton>
</Animator>For advanced use cases, access animation hooks directly:
import { useFadeAnimation, useSlideAnimation } from "@hoddy-ui/core";
const MyComponent = () => {
const { animatedStyle } = useFadeAnimation({
duration: 800,
closeAfter: 2000,
});
return (
<Animated.View style={animatedStyle}>
<CustomContent />
</Animated.View>
);
};import {
currencyFormatter,
numberFormatter,
errorMessage,
} from "@hoddy-ui/utils";
// Format currency
const price = currencyFormatter(1234.56); // "β¦ 1,234.56"
// Format phone numbers
const phone = numberFormatter("08012345678"); // "+234 801 234 5678"
// Extract error messages
const error = errorMessage(apiError); // Standardized error messageHoddy UI uses a comprehensive color system with semantic naming:
const colors = {
primary: { main: "#007AFF", light: "#5AC8FA", dark: "#0051D5" },
secondary: { main: "#FF3B30", light: "#FF6B6B", dark: "#D70015" },
white: ["#FFFFFF", "#F8F9FA", "#E9ECEF"],
black: ["#000000", "#212529", "#495057"],
blue: { main: "#007AFF", light: "#5AC8FA", dark: "#0051D5" },
// ... and many more
};const typography = {
h1: 42,
h2: 37,
h3: 32,
h4: 27,
h5: 22,
h6: 17,
body1: 15,
body2: 12,
caption: 10,
};- React Native: β₯ 0.71.8
- Expo: SDK 48+
- iOS: 11.0+
- Android: API 21+ (Android 5.0)
- TypeScript: β₯ 5.0.4
- Core Components API
- Migration Guide (coming soon)
- Examples - Sample implementation
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/kinghoddy/hoddy-ui.git
cd hoddy-ui
# Install dependencies
yarn install
# Run the test app
cd test/my-app
expo startMIT Β© Hoddy Inc
- GitHub Repository
- npm Package (@hoddy-ui/core)
- npm Package (@hoddy-ui/next)
- npm Package (@hoddy-ui/utils)
Found a bug or need help? Please open an issue on GitHub.
Made with β€οΈ by the Hoddy team