MangaNess is a React Native manga reading application built with Expo SDK 54, featuring a clean, ad-free reading experience with AniList integration, bookmark management, and comprehensive theming support.
- React Native 0.81.4 with React 19.1.0
- Expo SDK 54 with Expo Router for file-based navigation
- TypeScript with strict configuration
- Bun as package manager and runtime
- AsyncStorage for local data persistence
- Axios for HTTP requests
app/
├── _layout.tsx # Root layout with providers
├── (tabs)/ # Tab-based navigation
│ ├── _layout.tsx # Tab layout with swipe gestures
│ ├── index.tsx # Home screen
│ ├── mangasearch.tsx # Search functionality
│ ├── bookmarks.tsx # Bookmark management
│ ├── settings.tsx # App settings
│ └── manga/[id]/ # Dynamic manga routes
│ ├── index.tsx # Manga details page
│ └── chapter/[chapterNumber].tsx # Chapter reader
/components- Reusable UI components/services- Business logic and API integrations/hooks- Custom React hooks/types- TypeScript type definitions/constants- App constants and configuration/utils- Utility functions and helpers
Every component follows this structure:
// 1. Imports (grouped and ordered)
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { View, Text, StyleSheet, Pressable } from 'react-native';
import { useTheme } from '@/hooks/useTheme';
import { Colors } from '@/constants/Colors';
// 2. Type definitions
interface ComponentProps {
title: string;
onPress?: () => void;
disabled?: boolean;
}
// 3. Main component function
export default function ComponentName({ title, onPress, disabled }: ComponentProps) {
// 4. Theme and styling (always first)
const { actualTheme } = useTheme();
const colors = Colors[actualTheme];
const styles = getStyles(colors);
// 5. State management
const [loading, setLoading] = useState(false);
// 6. Memoized values and callbacks
const handlePress = useCallback(() => {
if (disabled || loading) return;
onPress?.();
}, [disabled, loading, onPress]);
// 7. Effects
useEffect(() => {
// Side effects
}, []);
// 8. Main render
return (
<Pressable style={[styles.container]} onPress={handlePress}>
<Text style={styles.title}>{title}</Text>
</Pressable>
);
}
// 9. Styles function (always at bottom)
const getStyles = (colors: typeof Colors.light) => StyleSheet.create({
container: {
backgroundColor: colors.background,
borderRadius: 8,
padding: 16,
},
title: {
color: colors.text,
fontSize: 16,
fontWeight: '600',
},
});Every component must use the theme system:
const { actualTheme, theme, setTheme, accentColor } = useTheme();
const colors = Colors[actualTheme]; // 'light' | 'dark'
const styles = getStyles(colors);const getStyles = (colors: typeof Colors.light) =>
StyleSheet.create({
// Container styles first
container: { backgroundColor: colors.background },
// Text styles grouped
title: { color: colors.text, fontSize: 24 },
// Interactive elements
button: { backgroundColor: colors.primary },
});- MangaItem - Search results (
types/manga.ts) - MangaDetails - Full manga information (
types/manga.ts) - MangaData - Storage model (
types/manga.ts) - BookmarkStatus - 'To Read' | 'Reading' | 'Read' | 'On Hold'
- Chapter - Chapter information (
types/manga.ts)
- ErrorType enum - Network, Validation, Cache, Parsing, etc. (
types/errors.ts) - Custom Error Classes - MangaNetworkError, MangaValidationError, etc.
- File:
utils/logger.ts - Usage: Import
logger()for all debugging and monitoring - Scopes: 'Navigation', 'Network', 'Service', 'Storage', 'UI'
- Features: Performance measurement, async operation tracking, buffered logging
- File:
utils/performance.ts - Usage: Import
performanceMonitoranduseRenderTimehook - Features: Component render timing, async operation measurement, metrics collection
- File:
utils/haptics.ts - Usage: Import
hapticFeedbackservice oruseHapticFeedbackhook - Types: Light, Medium, Heavy, Success, Warning, Error, Selection
- File:
utils/networkMonitor.ts - Usage: Call
installNetworkMonitor(axios)in app initialization - Features: Automatic request/response logging, timing, error tracking
- File:
services/mangaFireService.ts - Purpose: Main API integration for manga data
- Features: HTML parsing, caching, Cloudflare detection, retry logic
- File:
services/bookmarkService.ts - Purpose: Local bookmark and reading progress management
- Features: AsyncStorage operations, data consistency, migration support
- File:
services/anilistService.ts - Purpose: External manga tracking service integration
- Features: OAuth authentication, status synchronization, bulk operations
- File:
services/settingsService.ts - Purpose: App configuration and data management
- Features: Theme settings, data export/import, storage migration
- useNavigationHistory - History management (
hooks/useNavigationHistory.ts) - useSwipeBack - Gesture-based navigation (
hooks/useSwipeBack.ts)
- useTheme - Theme atom access (
hooks/useTheme.ts) - useThemeColor - Color resolution (
hooks/useThemeColor.ts)
- useHapticFeedback - Haptic feedback integration (
utils/haptics.ts) - useRenderTime - Performance measurement (
utils/performance.ts)
- MangaCard - Manga display card (
components/MangaCard.tsx) - Alert - Custom modal alerts (
components/Alert.tsx) - BackButton - Navigation back button (
components/BackButton.tsx) - SwipeChapterItem - Swipeable chapter list item (
components/SwipeChapterItem.tsx)
- ErrorBoundary - Error catching and fallback (
components/ErrorBoundary.tsx) - ThemedText/ThemedView - Theme-aware base components
- Components: PascalCase (e.g.,
MangaCard.tsx) - Services: camelCase with suffix (e.g.,
mangaFireService.ts) - Hooks: camelCase with
useprefix (e.g.,useSwipeBack.ts) - Types: camelCase (e.g.,
manga.ts) - Utils: camelCase (e.g.,
logger.ts)
- React and React Native imports
- Third-party library imports
- Internal imports (grouped by type)
- Relative imports (avoid if possible)
- Always use try-catch for async operations
- Log all errors with appropriate scope and context
- Use proper error types from the error system
- Implement retry logic for network operations
- Provide user-friendly error messages
- Use React.memo for expensive components
- Implement useCallback for event handlers
- Use useMemo for expensive calculations
- Implement proper list optimization with FlatList
- Monitor performance with the performance monitor
- Add accessibility labels to all interactive elements
- Use proper accessibility roles
- Support screen readers
- Test with accessibility tools
- Location:
__tests__/components/ - Tools: Jest, React Native Testing Library
- Pattern: Test behavior, not implementation
- Location:
__tests__/services/ - Tools: Jest with mocks
- Pattern: Mock external dependencies, test business logic
- File:
eas.json - Profiles: development, preview, production
- Environment: Variables in
constants/env.ts
- Development:
bun start,bun android,bun ios - Building:
bun run build,bun run build:ios - Quality:
bun run lint,bun run type-check,bun run test
- Always use the theme system - No hardcoded colors
- Log all operations - Use appropriate scopes and context
- Handle errors properly - Try-catch, logging, user feedback
- Optimize performance - Memoization, proper list handling
- Follow accessibility guidelines - Labels, roles, screen reader support
- Use TypeScript strictly - Proper types, no
any - Test thoroughly - Components and services
- Document complex logic - Comments for future maintainers
- Read the actual file for implementation details
- Follow established patterns in similar components
- Use existing utilities rather than creating new ones
- Maintain consistency with the codebase style
- Test changes thoroughly before submitting
This guide provides the essential information for working with the MangaNess codebase. For specific implementation details, always refer to the actual source files.