From Idea to App Store: Building a Cross-Platform Packing List App

Discover how we designed, built, and launched a production-grade mobile app from scratch, covering product strategy, offline-first architecture, multi-platform deployment, subscription monetization, and localization into 36 languages.

Project Overview

A Solo Full-Stack Product: Concept to App Store

Smart Packing List is a cross-platform mobile and web application that helps travelers organize their packing with reusable lists, hierarchical categories, and real-time cloud sync across devices. It works completely offline and syncs seamlessly when connectivity returns.

What sets this project apart from our typical consulting engagements is scope: this was a complete product built from the ground up. Every decision, from database schema to App Store pricing, was ours to make. The result is a production app available on iOS, Android, and the web, serving real users today.

Mobile App Development

What Makes This Project Unique

Unlike a typical consulting engagement where scope is defined by a client, this project required wearing every hat simultaneously:

  • Product Manager – Defined the feature roadmap, prioritized MVP scope, made pricing decisions
  • UX Designer – Created user flows, designed the category hierarchy system, built progressive disclosure patterns
  • Full-Stack Developer – Wrote every line of frontend, backend, and infrastructure code
  • DevOps Engineer – Set up CI/CD, managed Supabase environments (dev/prod), configured Edge Functions
  • Release Manager – Navigated Apple App Store and Google Play submission processes, handled compliance requirements

This breadth demonstrates not just coding ability, but the capacity to own and deliver an entire product lifecycle.

Challenges & Objectives

Overcoming Obstacles

The Core Problem

Existing packing list apps fall into two camps: oversimplified (just a checklist) or bloated with features that obscure the core task. We set out to build something in between – powerful enough to handle complex, reusable packing workflows, yet simple enough to use while rushing to catch a flight.

Technical Objectives
  • Offline-first reliability – The app must work flawlessly with zero connectivity (airports, flights, remote areas), then sync transparently when back online
  • True cross-platform – A single codebase serving iOS, Android, and web with native look and feel on each
  • Subscription monetization on all platforms – Stripe on web, Apple IAP on iOS, Google Play Billing on Android, each with server-side receipt validation
  • Global reach – Localization into 36 languages from day one, not as an afterthought
  • Production quality – Not a side-project demo, but a real product with proper error handling, data migration, account management, and compliance (GDPR, App Store guidelines)

Platforms Shipped

Languages Supported

%

Code Sharing Across Platforms

Payment Integrations

Edge Functions Deployed

%

Offline Capability

Solution & Approach

Offline-First Architecture with Real-Time Sync

The most significant architectural decision was choosing an offline-first approach with PowerSync as the sync layer between a local SQLite database and Supabase PostgreSQL.

How it works:

  • Every read and write happens against the local SQLite database – instant, no network dependency
  • PowerSync watches for local changes and uploads them to Supabase PostgreSQL
  • Supabase changes (from other devices) flow back through PowerSync’s WebSocket connection
  • Conflict resolution is handled automatically at the sync layer

Users packing for a trip are often in transit – poor WiFi, airplane mode, spotty hotel connections. The app never shows a loading spinner for basic operations. Data just appears, and sync happens silently in the background.

Database Design
  • Soft deletes on all main entities (trips, items, categories) – preserving data integrity across sync
  • Many-to-many relationships – Items can belong to multiple categories; trips reference reusable category templates
  • Denormalized packing state – Each trip preserves item names and quantities at packing time, so editing a master item doesn’t retroactively alter a completed trip’s history
  • Database abstraction layer – A unified interface allows transparent switching between LocalDatabase (free tier, no sync) and SyncedDatabase (premium, with PowerSync)
Multi-Platform Subscription Billing

Each platform has its own payment flow, but all converge to a single user_subscriptions table:

Web (Stripe): Stripe Checkout Session → webhook → Edge Function updates subscription status

iOS (Apple IAP): StoreKit purchase → App sends receipt to Edge Function → Apple receipt verification → Subscription updated

Android (Google Play): Google Play purchase → App sends token to Edge Function → Google API verification → Subscription updated

All receipt validation happens server-side via Supabase Edge Functions. The client never self-validates a purchase, preventing tampering and ensuring a single source of truth.

Capacitor: One Codebase, Native Experience

Using Capacitor 8, the React web app runs inside a native WebView on iOS and Android, with access to native plugins for:

  • Apple Sign-In and Google Sign-In
  • In-App Purchases (via cordova-plugin-purchase bridging StoreKit / Google Play Billing Library)
  • App review prompts at optimal moments
  • Safe area handling for modern device notches and home indicators

95%+ code sharing across all three platforms. Platform-specific code is isolated to thin service wrappers (e.g., appleBillingService.ts, googlePlayBillingService.ts, stripeBillingService.ts).

Technical Deep Dive

Hard Problems Solved

Capacitor WebView Silent Failures

Problem: The official Supabase client method for calling Edge Functions fails silently inside Capacitor’s WebView on mobile devices. No error, no response, just nothing.

Solution: Bypassed the Supabase client entirely for Edge Function calls. Used direct fetch() with manual Authorization: Bearer headers. This pattern is now used consistently across all mobile Edge Function interactions.

Takeaway: In hybrid mobile development, never assume a web SDK behaves identically inside a WebView. Always verify on-device.

Apple Receipt Validation Across Environments

Problem: Apple’s StoreKit 1 uses “unified receipts” (not the newer StoreKit 2 JWS tokens). The receipt data lives at an unexpected path, and sandbox vs. production receipt endpoints must be handled with a fallback strategy.

Solution: Built a validation Edge Function that attempts production validation first, then falls back to sandbox on status code 21007. Parses the unified receipt to extract original_transaction_id and expires_date for subscription tracking.

Takeaway: Apple IAP documentation is fragmented across StoreKit 1, StoreKit 2, and App Store Server API. Real-world implementation requires reading between the lines.

Offline-to-Online Data Migration

Problem: Free-tier users store data only in local SQLite. When they upgrade to premium, their existing local data must be uploaded to Supabase without losing anything, and without creating duplicates if the migration is interrupted.

Solution: Built a dedicated MigrationService with explicit state management (disabled, initializing, migrating, connecting, syncing). The service detects user changes, clears stale local data when switching accounts, and performs a one-time upload of local data to the cloud on first premium sync.

Edge Function JWT Verification

Problem: Supabase’s API gateway rejects valid ES256-signed JWTs from the auth service with a 401 error – a known edge case with certain token configurations.

Solution: Deployed Edge Functions with gateway JWT verification bypassed, then implemented token verification inside the function code itself. This provides the same security guarantee while avoiding the gateway bug.

Dynamic Imports in iOS WebView

Problem: Vite’s code-splitting produces dynamic import calls that break inside Capacitor’s iOS WebView when they use a Function constructor internally – blocked by WebView’s stricter CSP.

Solution: Configured the build to use standard import syntax and adjusted Vite’s chunking strategy to avoid the problematic construction pattern.

Technologies & Tools

Frontend

React 19, TypeScript, TailwindCSS, i18next (36 languages)

Mobile

Capacitor 8, cordova-plugin-purchase (Apple IAP + Google Play), App Review prompts

Backend & Infrastructure

Supabase (PostgreSQL, Auth, Edge Functions), PowerSync, Stripe, Vercel

DevOps & Quality

Vitest, Playwright, GitHub Actions CI/CD, SonarCloud-style code quality checks

Key Achievements

Results & Impact

N

Production App on Three App Stores

The app is live and serving real users on the Apple App Store, Google Play Store, and as a web application – all from a single TypeScript codebase.
N

Offline-First Architecture That Actually Works

Unlike many “offline-capable” apps that degrade gracefully, Smart Packing List is designed offline-first. The network is a nice-to-have for sync, not a requirement for functionality.
N

Freemium Model with Server-Validated Subscriptions

A complete subscription system with server-side receipt validation, free trial support, and platform-specific billing – ensuring revenue integrity while keeping the free tier genuinely useful.
N

Global-Ready from Day One

With 36 locales supported at launch, the app is ready for users worldwide. Localization is part of the component architecture, with every user-facing string externalized.
N

95%+ Cross-Platform Code Sharing

A single TypeScript codebase serves iOS, Android, and web. Platform-specific code is isolated to thin service wrappers, keeping the shared core clean and maintainable.
N

Real Engineering, Not a Tutorial Project

The codebase handles real-world complexity: data migration between tiers, multi-device session management, soft deletes with sync, cross-platform IAP receipt validation, and App Store compliance requirements.

Specific Features / Customizations

Offline-first changes everything: designing for offline first simplifies many UX decisions but introduces sync complexity that must be handled at the architecture level

Hybrid mobile is viable with caveats: Capacitor delivers on code reuse, but WebView edge cases require on-device testing for every feature. Emulators are not enough.

Multi-platform billing is the hardest “simple” problem: three payment processors, three receipt formats, three validation flows, all converging to one subscription state

App Store compliance is a product concern, not just a checklist: Apple and Google’s requirements shaped actual product decisions around subscription transparency, account deletion, and privacy

AI-assisted development at scale: this project was developed with significant use of AI coding assistants, demonstrating how a solo developer can ship a complex, multi-platform product that would traditionally require a team

Project Summary

Role Product Owner, Designer & Full-Stack Developer
Duration 2026 – ongoing
Stack React 19, TypeScript, Capacitor 8, Supabase, PowerSync
Platforms iOS (App Store), Android (Google Play), Web (Vercel)
Focus Area Offline-first sync, cross-platform IAP, 36-language localization, freemium monetization
Result Production app shipped to 3 platforms, demonstrating end-to-end product delivery capability

Reflection

This project represents the most comprehensive demonstration of our technical capabilities. While our SAP Commerce engagements showcase deep expertise in enterprise e-commerce, Smart Packing List proves we can take a product from a blank repository to a live, monetized, multi-platform application – handling everything from database schema design to App Store screenshot preparation. It also reflects a modern approach to software development: leveraging serverless infrastructure to build production-grade systems without managing servers, and using AI-assisted development to achieve the output of a small team as a solo developer. For consulting clients, this means we bring not just implementation skills, but product thinking – the ability to reason about trade-offs, prioritize ruthlessly, and ship something real.

Interested in Building a Mobile App or Cross-Platform Product?

Whether you need a full product build, a mobile app strategy, or help integrating subscription billing into your existing platform – we bring hands-on experience from shipping real products. Let’s discuss your project.

Want to See More Projects?

Explore how we’ve designed and developed modern, high-performing applications that strengthen digital presence and drive measurable results.