Skip to main content
강홍재/ James
← Work
MVP2026 · Solo Builder· Started(First Commit date)

ParkPin

A personal parking app that logs your spot by floor and zone and shows it on a home widget (iOS and Android) without opening the app - offline-first, local storage.

  • React Native / Expo
  • TypeScript
  • Home Widget (iOS/Android)
  • Offline-first
Screenshots
  • Onboarding - "never wander for your spot again." It leads with three things: tap-to-log, widget check, and per-vehicle saving

  • Home - the current spot shown large as "B3-A, next to the pillar," with the vehicle, lot, time, and map/share/leave buttons

  • Map - see the saved lot on a map and hand off to a maps app for directions

  • Tips - a set on parking etiquette, regulations, and plate privacy; the footer states these are general guidance and to defer to current rules

  • Lot setup - register floors and zones for a regular lot; outdoor parking saves straight as "outdoor" with no setup

  • History - entries, exits, and durations on a per-vehicle timeline (e.g. "parked 3h," "E-Mart P2-Strawberry")

  • My vehicles - register cars by license plate; with two or more, each car's spot is tracked separately

  • Share - turn the parking spot into an image card to send

  • Home widgets - check "B3-A, next to the pillar" right on the home screen without opening the app (multiple widget sizes)

Setup

Problem

You forget where you parked and lose time finding the car. Regular lots (with a floor/zone structure) and unfamiliar places (department stores) need different ways to record, so a single method doesn't capture both well.

Context

Started as a personal tool. Regular lots are logged structurally by floor and zone, unfamiliar places by a single free-text note, and each vehicle (license plate) is saved separately.

Build

What I did
  • Two ways to record - floor/zone taps for saved lots, a quick note for unfamiliar places
  • Per-vehicle (license plate) location saving + Korean plate-format validation
  • Home widget on both iOS and Android to check without opening the app - WidgetKit + App Group on iOS, react-native-android-widget on Android
  • Offline-first local storage (AsyncStorage) - works without a network and survives app restarts
  • Optional Supabase backend - accounts, social login, and cloud backup/sync; runs local-only when not configured
Product decisions
  • After parking, the screen keeps only the "I left" button and hides floor/zone/save - what you need when returning is a check, not a record
  • The widget as the main entry point - checking your spot shouldn't even require opening the app, so it ends in two lines on the home screen
  • Local-first - a personal parking spot must save and show instantly, even without a network or account; accounts and cloud sync sit on top as an optional Supabase backend, and it degrades to local-only when not configured
QA considerations
  • Where the widget and app split the same location data (iOS App Group) is the most regression-prone spot - the top priority is "does the location saved in the app always show correctly in the widget?"
  • Offline-first - saves and shows instantly without a network or account, and survives an app restart
  • Korean license-plate format validation is pinned by unit tests (the trust basis for per-vehicle saving)
  • When optional Supabase sync isn't configured, it degrades cleanly to local-only
  • Unit tests (jest) go first on storage, plate validation, display logic, and hooks to create a place to catch regressions

Outcome

Metrics
  • In closed testing on Android and iOS
  • Pre public store release (store-listing materials in preparation)
  • Landing/support page public at parkpin-app.pages.dev

Process (planning → build)

The same template from problem and hypothesis through scope, spec (SSOT), build, the QA gate, and release - how this was planned and driven.

Problem & hypothesis

Started to remove the time lost re-finding where I parked. The hypothesis: regular lots (with a floor/zone structure) and unfamiliar places need different ways to record, so one screen forks into two input modes (structured log / quick note).

Skills · Problem framing · hypothesis

Scope & priority

Pinned the scope by numbering features FR-001 to FR-013. Kept widget, offline, and per-vehicle saving as the core and pushed map, share, and tips to a later tier to keep the initial scope narrow.

Skills · Scoping · prioritization

Spec-first (SSOT)

Wrote screens, behavior, and acceptance criteria into docs/ParkPin_SSOT.md first and let the implementation follow it. docs/ParkPin_Dev_Workflow.md fixed the dev routine so a solo build wouldn't drift.

Skills · Spec · documentation

Build & iteration

Stood up the core in React Native/Expo, added the home widget on both iOS (WidgetKit) and Android (react-native-android-widget), then layered an optional Supabase sync on top for users who want accounts and backup.

Skills · Execution · delivery

Verification (QA gate)

Unit tests (jest) went first on storage, plate validation, display logic, and hooks. Since the widget and app hold the same location data across processes - the spot most prone to regressions - that state sync was the top verification priority.

Skills · Quality · risk

Release

Configured store submission via EAS; currently in closed testing on iOS and Android. A landing/support page is public at parkpin-app.pages.dev.

Skills · Release

Tech stack
  • React Native (Expo SDK 56)
  • TypeScript
  • iOS WidgetKit
  • react-native-android-widget
  • AsyncStorage
  • Supabase