From Idea to App Store: Building My First Mobile App in 6 Weeks
Development

From Idea to App Store: Building My First Mobile App in 6 Weeks

Ricardo Gil
January 5, 2026
40 min read
#React Native #Mobile Development #Expo #iOS #Android #App Store #Case Study #Open Source #TypeScript

The Idea

It was November 2024, and I had just wrapped up another intense week of .NET development work. I was sitting at my desk, thinking about a conversation I'd had with my wife, Daniela, about wanting to start our day with scripture but always forgetting to open the Bible app on our phones.

That's when it hit me: What if there was a dead-simple app that just showed you a random Bible verse every time you opened it? No accounts, no complexity, no distractions—just you and the Word.

I'd been wanting to publish something to the App Store for a while, partly to diversify my technical portfolio beyond web development, and partly because I was curious about the mobile app publishing process. This felt like the perfect project: simple enough to actually finish, useful enough to be meaningful, and focused enough to ship quickly.

The Problem I Wanted to Solve:

  • Existing Bible apps were overwhelming (thousands of features, reading plans, social features)
  • People wanted quick spiritual refreshment, not commitment
  • Language barrier for Spanish speakers (most apps were English-first)
  • Privacy concerns (too many apps collecting data)
  • My Goals: 1. Ship my first mobile app to the App Store 2. Learn React Native and Expo 3. Create something genuinely useful for daily spiritual life 4. Make it bilingual (English/Spanish) from day one 5. Keep it 100% free with no ads or tracking

    The Technical Stack

    I chose React Native with Expo for a few strategic reasons:

    Why React Native:

  • Write once, deploy to both iOS and Android
  • JavaScript/TypeScript (already familiar from my Angular work)
  • Huge ecosystem and community
  • Hot reload for fast development
  • Why Expo:

  • Managed workflow (no need for Xcode/Android Studio initially)
  • Over-the-air updates
  • Easy push notifications setup
  • EAS Build for cloud builds (no Mac needed for iOS builds!)
  • Full Stack:

    code
    Frontend: React Native 0.81
    Language: TypeScript 5.1
    Framework: Expo 54
    State Management: React Hooks (useState, useEffect)
    Storage: AsyncStorage (for offline data)
    API: Bolls.life Bible API (free, no auth)
    Navigation: Expo Router

    Why These Choices Matter:

    1. TypeScript: Type safety prevents stupid bugs. In a solo project, you ARE the QA team.

    2. AsyncStorage: All user data (favorites, downloaded books, preferences) stored locally. Zero backend costs, maximum privacy.

    3. Bolls.life API: After researching 5+ Bible APIs, this one was perfect: - Free and unlimited - Multiple translations - Simple REST endpoints - No authentication required - Support for verse-by-verse fetching (crucial for my offline feature)

    4. Expo Managed Workflow: I could build iOS apps from my Windows PC using EAS Build. Game-changer.

    The Development Journey

    Week 1: MVP (16 hours)

    Day 1-2: Core Functionality

    I started with the absolute minimum:

    typescript
    // The heart of the app - fetch a random verse
    const fetchVerse = async () => {
      const response = await fetch(
        https://bolls.life/get-random-verse/WEB/
      );
      const data = await response.json();
      const cleanText = data.text.replace(/<[^>]*>/g, ''); // Strip HTML tags
      
      setVerse({
        text: cleanText,
        reference: ${data.book} ${data.chapter}:${data.verse},
        translation_id: 'WEB'
      });
    };

    Key Decision: Strip HTML tags from API responses. The API returns formatted text with and tags. I wanted plain text for simplicity.

    Day 3: UI/UX Design

    I'm not a designer, so I kept it minimal:

  • Clean typography (large, readable text)
  • Warm color palette (sage green, warm brown, off-white)
  • Dark mode from day one
  • One main action: "New Verse" button
  • Design Philosophy: Remove everything that doesn't serve the core experience.

    Day 4-5: Essential Features

    Added three critical features: 1. Favorites: Long-press to save verses 2. Share: Export verses to social media 3. Copy: Quick clipboard copy

    typescript
    const toggleFavorite = async () => {
      const verseId = ${verse.reference}-${verse.translation_id};
      const newFavorite: SavedVerse = {
        ...verse,
        id: verseId,
        savedAt: Date.now()
      };
      await saveFavorites([newFavorite, ...favorites]);
    };

    Learning: React Native's Share API is beautiful—one line of code works on both platforms:

    typescript
    await Share.share({
      message: ${verse.text}\n\n— ${verse.reference}
    });

    Week 2: Going Bilingual (12 hours)

    The Spanish Challenge:

    I wanted Spanish support from day one because:

  • My family in Venezuela would use it
  • 50+ million Spanish speakers in the US
  • Most Bible apps treat Spanish as an afterthought
  • Implementation:

    typescript
    const translations = {
      en: {
        title: "Daily Bible Verse",
        newVerse: "New Verse",
        share: "Share",
        copy: "Copy"
      },
      es: {
        title: "Versículo Bíblico Diario",
        newVerse: "Nuevo Versículo",
        share: "Compartir",
        copy: "Copiar"
      }
    };

    Supported Translations:

  • English: WEB (World English Bible), KJV (King James), ASV (American Standard)
  • Spanish: RVR1960 (Reina-Valera), LBLA (La Biblia de las Américas), NVI (Nueva Versión Internacional)
  • UI Challenge: Language switcher needed to be intuitive. I used flag emojis (🇺🇸/🇪🇸) with a dropdown. Simple, visual, works everywhere.

    Week 3-4: The Offline Feature (20 hours)

    This was the hardest part—and the most rewarding.

    The Problem: Users wanted to read complete books offline (imagine flights, camping, poor signal areas).

    The Challenge: Download entire books verse-by-verse without overwhelming the API.

    My Solution:

    typescript
    const downloadBook = async (book: Book) => {
      const allVerses: BibleVerse[] = [];
      
      // Loop through each chapter
      for (let ch = 1; ch <= book.chapters; ch++) {
        let v = 1;
        let chapterComplete = false;
        
        while (!chapterComplete && v <= 250) {
          const url = https://bolls.life/get-verse/${translation}/${bookId}/${ch}/${v}/;
          const res = await fetch(url);
          
          if (!res.ok) {
            chapterComplete = true; // 404 = end of chapter
            break;
          }
          
          const data = await res.json();
          allVerses.push({
            text: data.text.replace(/<[^>]*>/g, ''),
            reference: ${bookName} ${ch}:${v},
            // ... more fields
          });
          
          v++;
          await new Promise(r => setTimeout(r, 50)); // Polite 50ms delay
        }
        
        // Update progress bar
        setProgress((ch / book.chapters) * 100);
      }
      
      // Save to AsyncStorage
      await AsyncStorage.setItem(book_${bookName}, JSON.stringify(allVerses));
    };

    Why This Approach:

    1. Polite crawling: 50ms delay between requests (don't abuse the free API!) 2. Chapter-by-chapter: Show progress, allow pause/resume 3. 404 detection: API returns 404 when verses run out (graceful ending) 4. Local storage: Once downloaded, completely offline

    Result: Users can download any of the 66 Bible books. Genesis = 1,533 verses, stored in ~300KB. The entire Bible = ~31,000 verses, ~6MB.

    UI Polish:

  • Real-time progress bar
  • Verse count updates as download progresses
  • Can read what's downloaded while download continues
  • Delete button to free up space
  • Week 5: Polish & Testing (8 hours)

    Responsive Design:

    Had to support:

  • Small phones (iPhone SE - 375px wide)
  • Regular phones (iPhone 14 - 390px)
  • Tablets (iPad - 768px+)
  • typescript
    const [dimensions, setDimensions] = useState(Dimensions.get('window'));

    useEffect(() => { const subscription = Dimensions.addEventListener('change', ({ window }) => { setDimensions(window); }); return () => subscription?.remove(); }, []);

    const isSmallDevice = dimensions.width < 375; const isTablet = dimensions.width >= 768;

    Dark Mode:

    System-aware dark mode with manual override:

    typescript
    const [themeMode, setThemeMode] = useState<'light' | 'dark' | 'system'>('system');

    const isDark = themeMode === 'dark' || (themeMode === 'system' && useColorScheme() === 'dark');

    Performance Optimization:

    1. Lazy loading for favorites (only load when tab opens) 2. Memoized components for verse display 3. Debounced search in downloaded books 4. Image optimization for app icon/splash

    Week 6: App Store Submission

    The Requirements:

    For Apple App Store:

  • Apple Developer account ($99/year)
  • App icons (1024x1024 PNG)
  • Screenshots (6.7" iPhone, 12.9" iPad)
  • Privacy policy
  • App description, keywords, category
  • Age rating (I chose 4+)
  • For Google Play:

  • Google Play Console ($25 one-time)
  • Feature graphic (1024x500)
  • Screenshots (phone + tablet)
  • Privacy policy
  • Store listing
  • Content rating
  • The Submission Process:

    Building the iOS App:

    bash
    # Configure EAS
    eas build:configure

    Build for iOS (cloud build, no Mac needed!)

    eas build --platform ios

    Submit to App Store Connect

    eas submit --platform ios

    The Review Process:

  • Apple: Submitted November 18, 2024
  • - Initial review: 24 hours - Rejected once (missing age rating explanation) - Fixed and resubmitted - Approved November 20, 2024 - Total time: 2 days

  • Google Play: Currently in closed testing
  • - 12 testers (friends, family, church members) - Running for 5 days - Collecting feedback before public launch

    What I Learned About App Review:

    1. Apple is stricter but faster: Clear guidelines, quick turnaround 2. Privacy policy is non-negotiable: Even if you collect zero data, you need one 3. Screenshots matter: I got feedback that mine could be more compelling 4. Keywords are limited: Apple allows 100 characters total. Choose wisely.

    The Technical Challenges

    Challenge #1: HTML in API Responses

    Problem: The API returns verses with HTML formatting:

    code
    "For God <em>so</em> loved the world..."

    Solution: Regex to strip tags:

    typescript
    const cleanText = text.replace(/<[^>]*>/g, '');

    Why not parse HTML? React Native doesn't have a built-in HTML parser, and I didn't want to add a dependency for this simple use case.

    Challenge #2: Verse Numbering Inconsistencies

    Problem: Different translations have different verse counts (some split verses, some combine them).

    Solution: The 404 detection pattern. When the API returns 404, that chapter is done. No hardcoded verse counts needed.

    Challenge #3: AsyncStorage Limits

    Problem: AsyncStorage has a 6MB limit on Android (10MB on iOS).

    Solution:

  • Compress data (remove whitespace from JSON)
  • Store books separately (not one giant object)
  • Warn users when approaching limit
  • Provide "clear all downloads" option
  • Challenge #4: Building iOS Without a Mac

    Problem: I develop on Windows. Xcode requires macOS.

    Solution: Expo EAS Build is magic. Upload your code, they build it on their servers, you get back an IPA file ready for App Store Connect.

    bash
    eas build --platform ios
    

    ☁️ Builds in the cloud

    📧 Email notification when done

    📦 Download IPA or submit directly

    Cost: $29/month for EAS priority builds (well worth it).

    Challenge #5: Keeping App Size Small

    Target: Under 25MB (psychological threshold for cellular downloads)

    Strategies: 1. No external fonts (use system fonts) 2. Optimized PNG icons (use TinyPNG) 3. No bundled images beyond icons 4. Tree-shaking unused Expo modules

    Result: 23.8 MB final app size ✅

    The Results

    App Store Metrics (First 6 Weeks)

    Downloads:

  • Total Units: 31 downloads
  • Impressions: 396 (154% increase week-over-week)
  • Conversion Rate: 7.8%
  • User Engagement:

  • Sessions: 18 active sessions
  • Retention: Users open app 3.2 times/week on average
  • Crashes: 0 (zero crashes! 🎉)
  • Revenue: $0 (completely free, no monetization)

    Rating: ⭐⭐⭐⭐⭐ 5.0 stars

    Google Play (Closed Testing)

    Testers: 12 people (friends, family, church members)

    Feedback Highlights:

  • "Love how simple it is - no distractions"
  • "Spanish support is perfect for my parents"
  • "Dark mode is beautiful"
  • "Offline books are a game-changer for flights"
  • Requested Features: 1. Search function (most requested) 2. Daily notifications (set time for daily verse) 3. Reading plans (structured Bible reading) 4. Bookmarks (mark position in downloaded books) 5. Verse highlighting/notes

    Open Source Impact

    GitHub Stats:

  • Stars: 3 ⭐
  • Forks: 1
  • Watchers: 2
  • Issues: 0 (no bugs reported!)
  • Why Open Source: 1. Portfolio showcase (proves I ship code) 2. Community contributions (future features) 3. Learning resource for other devs 4. Transparency (users can verify privacy claims)

    Repository: https://github.com/gilricardo-com/daily-bible-verse

    What I Learned

    Technical Lessons

    1. React Native Is Production-Ready

    Coming from Angular/web development, I was skeptical. But React Native works. The performance is good, the ecosystem is mature, and Expo removes most of the pain.

    2. Mobile UX Is Different

    Things I took for granted on web:

  • Hover states don't exist (use press states)
  • Back button means different things (Android vs iOS)
  • Safe areas matter (notch, home indicator)
  • Touch targets need to be 44x44pt minimum
  • Loading states are critical (poor connections common)
  • 3. Offline-First Is Complex

    I massively underestimated the offline feature. Edge cases everywhere:

  • What if download interrupted?
  • How to handle partial data?
  • How to clear/update cached data?
  • Storage limits?
  • Progress indication?
  • 4. APIs Can Be Simple

    The Bolls.life API is beautiful in its simplicity:

    code
    GET /get-random-verse/WEB/  → Random verse
    GET /get-verse/WEB/1/1/1/    → Genesis 1:1

    No authentication, no rate limits, no complexity. Sometimes simple is best.

    Business Lessons

    1. Scope Ruthlessly

    My original feature list had 20+ items. I shipped with 6 core features. The rest can wait.

    MVP mindset: What's the ONE thing this app must do well?

    2. Publish Fast, Iterate Later

    I waited too long perfecting things before submitting. Could have launched 2 weeks earlier and gotten real user feedback sooner.

    3. App Store Optimization Matters

    Bad keyword choices: "bible verse generator" (high competition) Good keyword choices: "daily bible verse offline" (specific, less competition)

    Bad screenshot: Just showing the app Good screenshot: Showing the benefit ("Read the Bible offline, anytime")

    4. Free Apps Can Succeed Without Monetization

    I have zero ads, no subscriptions, no freemium model. Just a useful tool.

    Why?

  • Builds trust and credibility
  • Portfolio piece (showcases skills)
  • Aligns with my values (faith-based content should be accessible)
  • Could monetize later if I want (donations, premium features)
  • Personal Lessons

    1. Shipping Feels Amazing

    There's something uniquely satisfying about seeing your app on the App Store. "I made this, and now strangers can use it."

    2. Imposter Syndrome Never Goes Away

    Even after building web apps professionally for 6+ years, I felt like a fraud publishing a mobile app. "Who am I to do this?"

    Do it anyway.

    3. Side Projects Are Worth It

    This project:

  • Taught me React Native
  • Gave me portfolio material
  • Led to interesting conversations with recruiters
  • Connected me with other Christian developers
  • Created something useful for people I care about
  • ROI: Priceless.

    4. Start Where You Are

    I didn't wait until I was an "expert" in mobile development. I had a need, researched for 2 days, and started building.

    6 weeks later, I had a published app.

    The Tech Stack Deep Dive

    Let me break down some key technical decisions:

    Why Expo Over Pure React Native?

    Expo Pros:

  • Managed workflow (less configuration)
  • OTA updates (fix bugs without app store review)
  • EAS Build (build iOS on Windows)
  • Push notifications setup is 5 lines of code
  • Expo modules are well-maintained
  • Expo Cons:

  • Slightly larger app size (~5MB overhead)
  • Some native modules not available
  • Less control over native code (can eject if needed)
  • Verdict: For 95% of apps, Expo is the right choice. I can always eject later if needed.

    State Management: Why No Redux/MobX?

    Simple truth: This app doesn't need it.

    State I manage:

  • Current verse (useState)
  • Favorites list (useState + AsyncStorage)
  • Downloaded books (useState + AsyncStorage)
  • UI state (modals, loading)
  • React hooks handle this perfectly. Adding Redux would be overengineering.

    When I'd use Redux:

  • Complex state shared across 10+ components
  • Time-travel debugging needed
  • Middleware requirements (logging, crash reporting)
  • Navigation: Expo Router

    I use Expo Router (file-based routing):

    code
    app/
      index.tsx        → Main screen
      favorites.tsx    → Favorites view
      book-detail.tsx  → Single book view
      settings.tsx     → Settings

    Why file-based routing?

  • Familiar (works like Next.js)
  • Deep linking built-in
  • Type-safe navigation
  • Less boilerplate than React Navigation
  • Styling: StyleSheet vs Styled Components?

    I use plain StyleSheet.create:

    typescript
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        padding: 20,
        backgroundColor: isDark ? '#1C1C1C' : '#F5F5F0'
      },
      verseText: {
        fontSize: isSmallDevice ? 20 : 24,
        lineHeight: 1.5,
        fontFamily: 'System'
      }
    });

    Why not styled-components?

  • StyleSheet is optimized by React Native
  • No runtime parsing
  • Better performance
  • Smaller bundle size
  • Trade-off: Less flexible, more verbose. But performance > convenience for mobile.

    The Features Breakdown

    Let me walk you through each feature's implementation:

    Feature #1: Random Verse

    How it works: 1. Call API: GET https://bolls.life/get-random-verse/WEB/ 2. Parse JSON response 3. Strip HTML tags 4. Display verse + reference

    Code:

    typescript
    const fetchVerse = async () => {
      setLoading(true);
      try {
        const url = https://bolls.life/get-random-verse/${selectedVersion[language]}/;
        const response = await fetch(url);
        const data = await response.json();
        
        setVerse({
          text: data.text.replace(/<[^>]*>/g, ''),
          reference: ${data.book} ${data.chapter}:${data.verse},
          translation_id: selectedVersion[language]
        });
      } catch (error) {
        setError(true);
      } finally {
        setLoading(false);
      }
    };

    Error handling:

  • Network error → Show "Try Again" button
  • API timeout → Show error message
  • Still allow access to offline content (favorites, downloaded books)
  • Feature #2: Favorites

    Storage structure:

    typescript
    interface SavedVerse {
      id: string;              // "John 3:16-WEB"
      text: string;
      reference: string;
      translation_id: string;
      savedAt: number;         // timestamp
    }

    Persisted in AsyncStorage:

    typescript
    await AsyncStorage.setItem('favorites', JSON.stringify(favorites));

    UI features:

  • Heart icon (filled when favorited)
  • Long-press on any verse to favorite
  • Swipe-to-delete in favorites list
  • Sort by date (newest first)
  • Feature #3: Share & Copy

    Share (native):

    typescript
    const handleShare = async () => {
      await Share.share({
        message: ${verse.text}\n\n— ${verse.reference} (${verse.translation_id})
      });
    };

    Copy (clipboard):

    typescript
    import * as Clipboard from 'expo-clipboard';

    const handleCopy = async () => { await Clipboard.setStringAsync( ${verse.text}\n\n— ${verse.reference} ); Alert.alert('✓', 'Copied to clipboard'); };

    Why both? Share opens system share sheet (WhatsApp, Instagram, etc.). Copy gives quick access for pasting elsewhere.

    Feature #4: Multi-Translation Support

    Available translations:

    English:

  • WEB (World English Bible) - Modern, public domain
  • KJV (King James Version) - Traditional, poetic
  • ASV (American Standard Version) - Literal translation
  • Spanish:

  • RVR1960 (Reina-Valera 1960) - Most popular in Latin America
  • LBLA (La Biblia de las Américas) - Modern, accurate
  • NVI (Nueva Versión Internacional) - Contemporary
  • Switching translations:

    typescript
    const changeVersion = async (versionCode: string) => {
      setSelectedVersion(prev => ({
        ...prev,
        [language]: versionCode
      }));
      await AsyncStorage.setItem(version_${language}, versionCode);
      
      // Reload current verse in new translation
      if (verse) {
        fetchSpecificVerse(verse.book, verse.chapter, verse.verse);
      }
    };

    UX detail: When switching translation, keep the same verse (re-fetch with new translation). Users can compare translations side-by-side.

    Feature #5: Offline Book Downloads

    The algorithm:

    typescript
    const downloadBook = async (book: Book) => {
      const bookId = bibleBooks.findIndex(b => b.name === book.name) + 1;
      const allVerses: BibleVerse[] = [];
      
      for (let chapter = 1; chapter <= book.chapters; chapter++) {
        let verse = 1;
        let chapterComplete = false;
        
        while (!chapterComplete) {
          const url = https://bolls.life/get-verse/${translation}/${bookId}/${chapter}/${verse}/;
          const response = await fetch(url);
          
          if (!response.ok) {
            chapterComplete = true; // 404 = no more verses
            continue;
          }
          
          const data = await response.json();
          allVerses.push({
            text: data.text.replace(/<[^>]*>/g, ''),
            reference: ${book.name} ${chapter}:${verse},
            chapter,
            verse
          });
          
          verse++;
          await sleep(50); // Polite delay
        }
        
        // Update progress
        setProgress((chapter / book.chapters) * 100);
      }
      
      // Save to storage
      const downloadedBook: DownloadedBook = {
        bookName: book.name,
        translation,
        verses: allVerses,
        downloadedAt: Date.now()
      };
      
      await AsyncStorage.setItem(
        book_${book.name}_${translation},
        JSON.stringify(downloadedBook)
      );
    };

    Progress indication:

    typescript
    const progress = (currentChapter / totalChapters) * 100;
    // Show progress bar: 0-100%
    // Also show verse count updating in real-time

    Memory management:

  • Download one book at a time
  • Allow cancellation mid-download
  • Clean up partial downloads if canceled
  • Feature #6: Dark Mode

    Implementation:

    typescript
    const [themeMode, setThemeMode] = useState<'light' | 'dark' | 'system'>('system');

    const isDark = themeMode === 'dark' || (themeMode === 'system' && useColorScheme() === 'dark');

    const styles = createStyles(isDark);

    Color palette:

    Light Mode:

  • Background: #F5F5F0 (warm off-white)
  • Text: #2C2C2C (dark gray)
  • Button: #4A5D4E (sage green)
  • Accent: #8B7355 (warm brown)
  • Dark Mode:

  • Background: #1C1C1C (true black)
  • Text: #E5E5E5 (light gray)
  • Button: #6B7C6E (muted sage)
  • Accent: #A89378 (light brown)
  • Why not pure black? OLED burn-in concerns. Also, pure black (#000000) looks harsh. Slightly off-black is more comfortable.

    The App Store Optimization (ASO) Strategy

    Title & Subtitle

    Title: "Daily Random Bible Verse"

    Why this works:

  • Contains main keyword: "Bible Verse"
  • Explains core function: "Daily" + "Random"
  • Short enough to display fully (under 30 chars)
  • Subtitle (iOS): "Scripture Inspiration & Offline Reading"

    Why this works:

  • Secondary keywords: "Scripture", "Inspiration", "Offline"
  • Benefit-focused, not feature-focused
  • Keywords (100 character limit)

    My choices:

    code
    bible,verse,daily,scripture,offline,spanish,devotional,christian,faith,quotes,king james,rv1960

    Research process: 1. Used App Store search suggestions 2. Checked competitor keywords (Bible Gateway, YouVersion) 3. Prioritized low-competition, high-intent keywords 4. Included Spanish terms (bilingual advantage)

    Avoided:

  • Generic terms: "app", "free", "best"
  • Brand names: Can't rank for "YouVersion"
  • Duplicates: Title already contains "daily bible verse"
  • Screenshots (6.7" iPhone)

    Screenshot 1 - Hero Shot:

  • Shows main screen with verse
  • Overlay text: "Daily Scripture Inspiration"
  • Clean, beautiful, immediately understandable
  • Screenshot 2 - Dark Mode:

  • Same layout in dark mode
  • Overlay: "Beautiful in Any Light"
  • Screenshot 3 - Offline Feature:

  • Downloaded books list
  • Overlay: "Complete Bible Books Offline"
  • Screenshot 4 - Bilingual:

  • Spanish interface
  • Overlay: "Disponible en Español"
  • Screenshot 5 - Features:

  • List of features with icons
  • No text overlay (let features speak)
  • Design principles:

  • Use real app UI (not marketing mockups)
  • Overlay text readable from thumbnail
  • Show benefits, not features
  • Demonstrate actual use
  • App Description

    First 170 characters (preview):

    code
    Start each day with inspiration from the Bible. Daily Random Bible Verse delivers Scripture in English or Spanish, with complete offline reading.

    Why this works:

  • Benefit first: "Start each day with inspiration"
  • Keywords naturally included
  • Addresses pain point: "complete offline reading"
  • Full description structure: 1. Hook (2 sentences): What it does, who it's for 2. Key features (bullet list): 6 main features 3. Translations (paragraph): Detail language support 4. Privacy (paragraph): No data collection, no ads 5. Open source (paragraph): Link to GitHub 6. Call to action: "Download now and start your daily journey with Scripture"

    Category Selection

    Primary: Books & Reference Secondary: Lifestyle

    Why not "Reference" only? Too competitive. "Lifestyle" has less competition in Bible app space.

    Pricing

    Free (no IAP, no subscriptions)

    Why? 1. Removes barrier to download 2. Aligns with mission (make Scripture accessible) 3. Portfolio piece (doesn't need to make money) 4. Could add donations later if desired

    Localization

    Languages supported:

  • English (US)
  • Spanish (Latin America)
  • Localized elements:

  • App name
  • Description
  • Screenshots
  • Keywords
  • Impact: Shows up in Spanish App Store searches, appeals to bilingual users.

    Roadmap: What's Next

    Based on tester feedback and my vision, here's what's coming:

    Phase 2: Core Enhancements (Q1 2025)

    1. Search Functionality ⭐ Most requested

    Find specific verses by:

  • Book, chapter, verse (e.g., "John 3:16")
  • Keywords (e.g., "love", "faith")
  • Topic (e.g., "hope", "forgiveness")
  • Technical approach:

  • Index all downloaded books locally
  • Use fuzzy matching for keywords
  • Highlight search terms in results
  • 2. Daily Notifications

    Push notification at user-selected time:

  • "Good morning! Here's today's verse..."
  • Customizable time
  • Randomized verse from user's preferred translation
  • Technical approach:

  • Expo Notifications API
  • Local notifications (no server needed)
  • Permission request with clear explanation
  • 3. Reading Plans

    Structured Bible reading:

  • "Read the Bible in a Year"
  • "Gospels in 30 Days"
  • "Psalms & Proverbs Monthly"
  • UI:

  • Progress tracking
  • Checkmarks for completed readings
  • Reminder notifications
  • Phase 3: Community Features (Q2 2025)

    4. Verse of the Day (Community)

    See what verse other users are reading:

  • Global VOTD (voted by community)
  • Most favorited verses this week
  • Trending verses
  • Privacy: Anonymous voting, no personal data

    5. Sharing Improvements

    Enhanced sharing:

  • Instagram Stories integration (beautiful templates)
  • Verse images (generated on-device)
  • Quote-style formatting
  • 6. Reading Streaks

    Gamification (light touch):

  • Track consecutive days opened
  • Milestone achievements
  • No pressure, just encouragement
  • Phase 4: Premium Features (Q3 2025)

    7. Advanced Study Tools

    For serious Bible students:

  • Cross-references
  • Commentaries (public domain)
  • Original language tools (Hebrew/Greek)
  • Word studies
  • Monetization: $2.99/month or $19.99/year

    Why premium? Advanced features require:

  • Larger datasets
  • More complex UI
  • Server costs (for syncing notes)
  • 8. Cloud Sync

    Sync across devices:

  • Favorites
  • Reading progress
  • Notes (if added)
  • Downloaded books
  • Backend: Firebase (free tier sufficient for thousands of users)

    Long-Term Vision

    The Goal: Not to compete with YouVersion or Bible Gateway (they're amazing).

    Instead: Be the simplest, most beautiful, most accessible Bible app for daily inspiration.

    Core principles:

  • ✅ Remain free for core features
  • ✅ No ads, ever
  • ✅ Privacy-first
  • ✅ Open source
  • ✅ Multilingual
  • ✅ Offline-first
  • For Aspiring App Developers

    If you're thinking about building your first mobile app, here's my advice:

    1. Start Stupid Simple

    Your first app should do ONE thing well. Don't build the next Instagram.

    Good first apps:

  • Random quote generator
  • Tip calculator
  • Unit converter
  • Daily reminder app
  • Simple timer
  • Bad first apps:

  • Social network
  • Complex game
  • E-commerce platform
  • Anything requiring complex backend
  • 2. Use Expo

    Seriously. Don't fight me on this.

    Yes, you give up some control. Yes, the app is slightly larger. But you'll ship 10x faster.

    Start here:

    bash
    npx create-expo-app my-first-app
    cd my-first-app
    npm start

    In 2 minutes, you're running an app on your phone.

    3. Ship Fast, Learn Faster

    My timeline:

  • Week 1-2: Build MVP
  • Week 3-4: Polish + testing
  • Week 5: Submit to stores
  • Week 6: Iterate based on feedback
  • Your timeline should be similar.

    Don't spend 6 months perfecting before launch. Ship in 4-6 weeks. Get real users. Learn. Iterate.

    4. Read These First

    Essential reading: 1. React Native Docs - Start here 2. Expo Docs - Your best friend 3. App Store Review Guidelines - Read before building 4. Play Store Policies - Same

    Helpful tutorials:

  • React Native basics (Traversy Media)
  • Expo crash course (Programming with Mosh)
  • 5. Tools I Used

    Development:

  • VS Code (with React Native extension)
  • Expo Go app (for testing on real device)
  • React Native Debugger
  • Design:

  • Figma (mockups/wireframes)
  • Coolors.co (color palette generator)
  • TinyPNG (image compression)
  • Icon/Splash:

  • Figma (design)
  • Icon.kitchen (iOS icons from one image)
  • App Icon Generator (Android adaptive icons)
  • Testing:

  • iPhone 14 (physical device)
  • Expo Go (quick testing)
  • TestFlight (iOS beta testing)
  • Deployment:

  • EAS CLI (build + submit)
  • App Store Connect (Apple)
  • Google Play Console (Android)
  • 6. Budget Reality Check

    Costs to publish an app:

    One-time:

  • Google Play: $25 (lifetime)
  • Apple Developer: $99/year
  • Domain (optional): $12/year
  • Monthly (if using Expo EAS):

  • Free tier: 30 builds/month (plenty for solo dev)
  • Paid tier: $29/month (unlimited builds + priority)
  • Total first year: $136-$484

    My spending: $205 (Apple $99 + Google $25 + Expo $29x3 months)

    7. Common Mistakes to Avoid

    Mistake #1: Not testing on real devices

    Simulators lie. Test on actual phones. Beg, borrow, or rent if you must.

    Mistake #2: Ignoring platform differences

    iOS and Android are different. Especially:

  • Navigation patterns
  • Back button behavior
  • Push notification permissions
  • Status bar handling
  • Mistake #3: Over-engineering

    You don't need:

  • Redux (probably)
  • Complex folder structure
  • Microservices
  • Advanced testing setup (for v1)
  • You DO need:

  • Basic error handling
  • Loading states
  • Offline behavior
  • Good UX
  • Mistake #4: Perfectionism

    Ship the 80% solution. Iterate.

    Perfect is the enemy of done.

    Mistake #5: Not reading guidelines

    Apple and Google reject apps for stupid reasons:

  • Missing privacy policy
  • Crashes on launch
  • Incomplete functionality
  • Misleading descriptions
  • Read. The. Guidelines.

    8. Your Launch Checklist

    Pre-launch (1 week before):

  • [ ] App tested on 3+ devices
  • [ ] All features work offline
  • [ ] Error states handled
  • [ ] Loading states everywhere
  • [ ] Privacy policy written
  • [ ] Screenshots designed
  • [ ] App description written
  • [ ] Keywords researched
  • Launch day:

  • [ ] Submit to both stores
  • [ ] Share on Twitter/LinkedIn
  • [ ] Post in relevant subreddits (respectfully!)
  • [ ] Tell friends/family
  • [ ] Add to portfolio/resume
  • [ ] Update GitHub README
  • Post-launch (first week):

  • [ ] Monitor crash reports
  • [ ] Read user reviews
  • [ ] Fix critical bugs ASAP
  • [ ] Plan v1.1 features
  • [ ] Respond to user feedback
  • Conclusion

    Building and publishing my first mobile app was one of the most rewarding experiences of my development career. It combined:

  • Technical learning (React Native, mobile UX, app stores)
  • Product thinking (what do users actually need?)
  • Execution (shipping something real)
  • Total time invested: ~60 hours over 6 weeks

    Total cost: $205

    Result: A published iOS app with real users, open source code showcasing my skills, and invaluable learning experience.

    Most importantly: I created something useful. People use it daily for spiritual inspiration. That matters more than downloads or revenue.

    Your Turn

    Whether you're a seasoned web developer curious about mobile, a bootcamp grad building your portfolio, or someone with an idea and no technical background—you can do this.

    Mobile app development is more accessible than ever:

  • Tools are better (Expo, React Native)
  • APIs are free (Bolls.life, and thousands of others)
  • Documentation is excellent
  • Community is helpful
  • You don't need:

  • A Mac (EAS Build handles iOS)
  • Years of experience
  • A big budget
  • A team
  • You DO need:

  • An idea
  • Willingness to learn
  • 4-6 weeks of focused work
  • $136 (minimum)
  • That's it.

    ---

    Links & Resources

    App:

  • 📱 Download on App Store
  • 🤖 Google Play (coming soon - in closed testing)
  • Code:

  • 💻 GitHub Repository
  • 📋 MIT License (open source!)
  • API:

  • 📖 Bolls.life Bible API (free, no auth)
  • Tools:

  • ⚛️ React Native
  • 📦 Expo
  • 🏗️ EAS Build
  • Contact:

  • ✉️ contact@gilricardo.com
  • 💼 LinkedIn
  • 🌐 Portfolio
  • ---

    About the Author:

    Ricardo Gil is a Full Stack Software Engineer with 6+ years of experience specializing in C#/.NET Core, Angular, and PostgreSQL. Originally from Venezuela, he immigrated to the United States in 2015 and has built scalable applications for healthcare, hospitality, and e-commerce industries. "Daily Random Bible Verse" is his first published mobile application, combining his technical expertise with his faith to create a tool for daily spiritual inspiration.

    ---

    If you found this helpful, please star the GitHub repo and share this post with other aspiring app developers. Your support means the world!

    Have questions about the app or mobile development in general? Leave a comment or email me at contact@gilricardo.com.

    Related Posts

    Building with Angular + Firebase? Check out my Photography E-Commerce Platform that combines Firebase auth with Stripe payments and AWS S3 storage.

    Self-hosting your projects? Learn how I host production apps on a Raspberry Pi with PM2, Nginx, and Tailscale.

    About the Author: Ricardo Gil is a full-stack software engineer specializing in .NET/C#, Angular, and cloud platforms. Read more or subscribe for updates.

    📬Weekly Newsletter

    Get the best home lab & AI content

    No spam. One email per week. Unsubscribe anytime.

    Share this article