react-native-pre-2026

React Native App Planning Document

Overview

This document outlines the plan for building a React Native version of HiveJournal, allowing users to journal on iOS and Android devices while sharing the same backend infrastructure.

Current Architecture

Web App (Next.js)

  • Frontend: Next.js 14 (App Router), TypeScript, Tailwind CSS
  • Backend: Node.js/Express API (Railway)
  • Database & Auth: Supabase (PostgreSQL + Auth)
  • Storage: Supabase Storage
  • Payments: Stripe
  • Email: Resend

Key Features

  1. Authentication: Email/password, magic links, OAuth
  2. Journal Entries: Create, read, update, delete entries
  3. Dashboard: Infinite scroll, search, filters
  4. Entry Viewer: Rich text display with custom fonts, backgrounds
  5. Entry Editor: Rich text editing with auto-save
  6. Notebooks: Organize entries into notebooks
  7. AI Features: Custom background image generation
  8. Settings: User preferences, themes, fonts
  9. Admin Panel: User management, impersonation
  10. Positive Notes: Random gratitude/positive notes display
  11. Stream View: Alternative entry viewing mode
  12. Goals: Accountability goals and check-ins

React Native Architecture

apps/
├── frontend/          # Next.js web app (existing)
├── backend/          # Express API (existing)
└── mobile/           # React Native app (new)
    ├── src/
    │   ├── screens/      # Screen components
    │   ├── components/   # Reusable components
    │   ├── navigation/   # Navigation setup
    │   ├── services/     # API clients, Supabase
    │   ├── hooks/        # Custom hooks
    │   ├── contexts/     # React contexts
    │   ├── utils/        # Utility functions
    │   └── types/        # TypeScript types
    ├── ios/              # iOS native code
    ├── android/          # Android native code
    └── package.json

Technology Choices

  1. React Native Framework:

    • Expo (recommended) - Easier setup, OTA updates, managed workflow
    • OR React Native CLI - More control, bare workflow
  2. Navigation:

    • React Navigation (v6+) - Industry standard, TypeScript support
  3. State Management:

    • React Context + Hooks (for simple state)
    • Zustand or Jotai (if needed for complex state)
    • React Query (for server state/caching)
  4. UI Components:

    • React Native Paper or NativeBase (component library)
    • React Native Reanimated (animations)
    • React Native Gesture Handler (gestures)
  5. Styling:

    • StyleSheet API (built-in)
    • Styled Components or Emotion (CSS-in-JS)
    • Tailwind Native (if you want Tailwind-like syntax)
  6. Supabase Integration:

    • @supabase/supabase-js (same as web)
    • @react-native-async-storage/async-storage (for session storage)
  7. Forms:

    • React Hook Form (form validation)
    • Zod (schema validation)
  8. Date Handling:

    • date-fns (same as web, works in RN)
  9. Image Handling:

    • expo-image or react-native-fast-image (performance)
  10. Rich Text Editing:

    • react-native-pell-rich-editor or @react-native-richtexteditor/richtexteditor

Shared Code Strategy

packages/
├── shared/
│   ├── types/          # Shared TypeScript types
│   ├── utils/          # Shared utilities (date formatting, etc.)
│   ├── constants/      # Shared constants
│   └── api-client/     # Shared API client (if possible)
└── ui/                 # Shared UI components (if using React Native Web)

Benefits:

  • Type safety across platforms
  • Single source of truth for business logic
  • Easier maintenance

Challenges:

  • Some utilities may need platform-specific implementations
  • UI components can't be fully shared (web vs native)

Option 2: Copy and Adapt

  • Copy relevant utilities and adapt for React Native
  • Less coupling but more maintenance
App Navigator (Stack)
├── Auth Stack
│   ├── Sign In
│   ├── Sign Up
│   └── Forgot Password
│
└── Main Stack (Tab Navigator)
    ├── Dashboard Tab
    │   ├── Dashboard (list of entries)
    │   ├── Entry Detail
    │   └── Entry Editor (new/edit)
    │
    ├── Stream Tab (optional)
    │   └── Stream View
    │
    ├── Notebooks Tab (optional)
    │   ├── Notebooks List
    │   └── Notebook Detail
    │
    ├── Goals Tab (optional)
    │   ├── Goals List
    │   └── Goal Detail
    │
    └── Settings Tab
        ├── Settings
        ├── Profile
        └── Admin (if admin)

Key Screens & Components

1. Authentication Screens

  • Sign In: Email/password, magic link option
  • Sign Up: Registration form
  • Session Management: Auto-refresh, secure storage

2. Dashboard Screen

  • Entry Cards: Similar to web, optimized for mobile
  • Infinite Scroll: Use FlatList with onEndReached
  • Search Bar: Sticky header with search
  • Filters: Drawer or modal for filters
  • Pull to Refresh: Native refresh gesture

3. Entry Detail Screen

  • Rich Text Display: Custom fonts, backgrounds
  • Actions: Edit, delete, share, AI background
  • Navigation: Swipe between entries (optional)
  • Back Button: Preserve scroll position

4. Entry Editor Screen

  • Rich Text Editor: Formatting toolbar
  • Auto-save: Save drafts locally + sync
  • Title Input: Separate from content
  • Tags Input: Chip-based tag selector
  • Mood Selector: Quick mood picker
  • Font/Background Picker: Modal selectors
  • AI Panel: Same as web for background generation

5. Settings Screen

  • Profile: Avatar, name, email
  • Preferences: Theme, default font, etc.
  • Account: Password change, delete account
  • Subscription: Payment management (Stripe SDK)

API Integration

Supabase Client Setup

// apps/mobile/src/services/supabase.ts
import { createClient } from '@supabase/supabase-js'
import AsyncStorage from '@react-native-async-storage/async-storage'

const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL!
const supabaseKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!

export const supabase = createClient(supabaseUrl, supabaseKey, {
  auth: {
    storage: AsyncStorage,
    autoRefreshToken: true,
    persistSession: true,
    detectSessionInUrl: false, // Not needed for mobile
  },
})

Backend API Client

// apps/mobile/src/services/api.ts
import { supabase } from './supabase'

const API_URL = process.env.EXPO_PUBLIC_API_URL!

export async function apiRequest<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<T> {
  const { data: { session } } = await supabase.auth.getSession()
  
  const headers: Record<string, string> = {
    ...(options.headers as Record<string, string>),
  }
  
  if (session?.access_token) {
    headers['Authorization'] = `Bearer ${session.access_token}`
  }
  
  if (options.body && !(options.body instanceof FormData)) {
    headers['Content-Type'] = 'application/json'
  }
  
  const response = await fetch(`${API_URL}${endpoint}`, {
    ...options,
    headers,
  })
  
  if (!response.ok) {
    const error = await response.json().catch(() => ({ message: 'An error occurred' }))
    throw new Error(error.message || 'Request failed')
  }
  
  const text = await response.text()
  if (!text) return {} as T
  
  try {
    return JSON.parse(text) as T
  } catch {
    return text as T
  }
}

Authentication Flow

  1. Sign In/Up: Use Supabase Auth (same as web)
  2. Session Persistence: AsyncStorage (handled by Supabase client)
  3. Token Refresh: Automatic via Supabase client
  4. Deep Linking: Handle auth callbacks (magic links, OAuth)

Deep Linking Setup

// Handle OAuth/magic link callbacks
import * as Linking from 'expo-linking'

useEffect(() => {
  const handleDeepLink = async (url: string) => {
    // Extract tokens from URL
    const { data, error } = await supabase.auth.getSessionFromUrl(url)
    if (error) {
      console.error('Auth error:', error)
    }
  }
  
  Linking.addEventListener('url', ({ url }) => {
    handleDeepLink(url)
  })
  
  // Check initial URL (app opened from link)
  Linking.getInitialURL().then((url) => {
    if (url) handleDeepLink(url)
  })
}, [])

Platform-Specific Considerations

iOS

  • App Store Guidelines: Privacy policies, subscription handling
  • Face ID/Touch ID: Biometric authentication (optional)
  • Haptic Feedback: Enhanced UX
  • Share Sheet: Native sharing of entries
  • Widgets: Home screen widgets (future)

Android

  • Material Design: Follow Material Design guidelines
  • Back Button: Handle Android back button
  • Permissions: Storage, camera (if needed)
  • Share Intent: Native sharing
  • Widgets: Android widgets (future)

Offline Support

Strategy

  1. Local Storage: Store entries in AsyncStorage/SQLite
  2. Sync Queue: Queue API calls when offline
  3. Conflict Resolution: Last-write-wins or manual merge
  4. Indicators: Show sync status, offline badge

Implementation

  • Use @react-native-async-storage/async-storage for simple data
  • Use react-native-sqlite-storage or watermelondb for complex queries
  • Use @tanstack/react-query with offline support

UI/UX Adaptations

Mobile-First Design

  • Touch Targets: Minimum 44x44pt (iOS), 48dp (Android)
  • Swipe Gestures: Swipe to delete, swipe between entries
  • Pull to Refresh: Native refresh pattern
  • Bottom Navigation: Tab bar at bottom (iOS/Android standard)
  • Floating Action Button: Quick "New Entry" button

Dark Mode

  • Use React Native's Appearance API
  • Match web app's dark mode implementation
  • System preference + manual toggle

Typography

  • Load custom fonts (same as web)
  • Responsive font sizes based on screen size
  • Support for user's system font size preferences

Images

  • Lazy loading for entry images
  • Placeholder images while loading
  • Optimize image sizes for mobile

Development Roadmap

Phase 1: Foundation (Week 1-2)

  • Set up Expo/React Native project
  • Configure navigation (React Navigation)
  • Set up Supabase client
  • Set up API client
  • Implement authentication screens
  • Set up shared types package

Phase 2: Core Features (Week 3-4)

  • Dashboard screen with entry list
  • Entry detail screen
  • Entry editor screen (basic)
  • Infinite scroll and pagination
  • Search functionality
  • Pull to refresh

Phase 3: Enhanced Features (Week 5-6)

  • Rich text editor
  • Custom fonts and backgrounds
  • Tags and mood selection
  • Notebooks support
  • Settings screen
  • Profile management

Phase 4: Advanced Features (Week 7-8)

  • AI background generation
  • Offline support
  • Image uploads
  • Push notifications (optional)
  • Deep linking
  • Share functionality

Phase 5: Polish & Testing (Week 9-10)

  • UI/UX refinements
  • Performance optimization
  • Error handling
  • Testing on iOS and Android
  • App Store preparation
  • Beta testing

Environment Variables

# .env (mobile app)
EXPO_PUBLIC_SUPABASE_URL=your_supabase_url
EXPO_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
EXPO_PUBLIC_API_URL=https://your-backend.railway.app

Testing Strategy

  1. Unit Tests: Jest for utilities and hooks
  2. Component Tests: React Native Testing Library
  3. E2E Tests: Detox or Maestro
  4. Manual Testing: TestFlight (iOS), Internal Testing (Android)

Deployment

iOS

  1. Apple Developer Account: Required ($99/year)
  2. App Store Connect: Create app listing
  3. Build: eas build --platform ios
  4. Submit: eas submit --platform ios

Android

  1. Google Play Console: Create app listing
  2. Build: eas build --platform android
  3. Submit: eas submit --platform android

OTA Updates (Expo)

  • Use Expo Updates for over-the-air updates
  • Push updates without app store review
  • Rollback capability

Challenges & Solutions

Challenge 1: Rich Text Editing

Solution: Use react-native-pell-rich-editor or build custom with WebView

Challenge 2: Custom Fonts

Solution: Load fonts in native projects, use fontFamily in styles

Challenge 3: Background Images

Solution: Use ImageBackground component, cache images

Challenge 4: Infinite Scroll Performance

Solution: Use FlatList with getItemLayout, removeClippedSubviews

Challenge 5: Offline Sync

Solution: Implement queue system, use React Query's offline support

Next Steps

  1. Decision: Expo vs React Native CLI
  2. Set up project structure
  3. Create shared types package
  4. Implement authentication flow
  5. Build first screen (Dashboard)

Resources

REACT NATIVE PLAN — Docs | HiveJournal