← All work
Four iterations · Not yet adopted React PWA · Supabase

Off the Shelf: shopping built for the island run

A household shopping companion built for how shopping actually works on Hawaiʻi Island.

Role
Product manager and builder
Built for
Two-person household, one account
Stack
React, TypeScript, Supabase, PWA
Status
Deployed, not yet adopted

The story in three parts

01 · Problem

Stores in different cities

On Hawaiʻi Island the stores you need are in different cities, and generic list apps don't know which store an item is in or what survives a hot car.

02 · Built

Features taken from real lists

Per-store aisle-sorted lists, city-run planning, a purchase memory and in-aisle questions, derived from real shopping lists across four iterations.

03 · Result

Used once, not adopted

It has been used on one real trip and not since. On that trip it lost to the notes app in the aisle, because the list inside it could not be trusted.

The island run in 20 seconds

What the work turned up

Real lists decided the structure

Each iteration loaded an actual shopping list and let it decide what came next, instead of inventing features up front.

It broke in the store, not before the trip

Setup happened before leaving. In the aisle, the list inside the app could not be trusted, and the notes app won.

Every blocker was checked against the code

A store needed on every imported row, every imported item defaulting to keep cool, typed notes lost on leaving the app: each one verified in the code.

01 · The problem

A shopping day is a city run

On Hawaiʻi Island, the stores you need are in different cities, so a shopping day is not one stop but a multi-store "city run" (a Kona run might hit Costco, Target, and Home Depot) followed by a long, hot drive home. Generic list apps ignore all of that. They don't know which store an item is in, which city you're driving to, what survives a hot car, or what the household already tried and disliked.

A pickup bed loaded with a cooler, paper grocery bags, a boxed item and a bag of soil, parked by low storefronts with a two-lane highway running toward a volcano.
A shopping day on the island is a run between towns, and it ends with a long, hot drive home.

Who it's for

A two-person household sharing one account, one person shopping while the other adds items and answers questions from home.

02 · What it does

What it does

  • Per-store lists sorted by aisle code, and within a store the items marked heat-safe group first so perishables are bought last, right before the drive.
  • City-run planning: pick a city and get a sequenced multi-store route.
  • A purchase memory records what the household tried, liked, and rejected, so an aisle decision becomes "we had this, never again" instead of a guess.
  • Two-way in-aisle questions: the shopper snaps a photo and asks, and the person at home can flag an item as photo-requested before it is bought.
  • Household members with per-member reactions, staples with one-tap re-add, returns and errands, a "parked" status for the not-yet items, and a paste importer that ingests messy real-world lists.
03 · Real lists

How the features came from real lists

The feature set was not invented up front.

It was derived from real shopping lists across four documented iterations, each one loading actual data at the destination and letting it decide the structure.

  1. v1 was a generic scaffold.
  2. v2 added the real islands and cities, and made a city run, not a single store, the unit of a trip.
  3. v3 came after ingesting a real Hilo and Target list: household members, aisle-code sorting, staples, returns, and the paste importer.
  4. v4 came from a real Costco list: shopper instruction notes (brand, "only if not expensive"), the photo-requested flag, and the parked status.
A crumpled handwritten list on a wooden table beside the same groceries sorted into groups: dry goods and household items, produce, and cold items next to a cooler.
A messy list becomes groups by store and aisle, with the cold items last.

The lesson is the method: structure was designed from real user data, loaded at the destination, never invented. Each list exposed what a generic app was missing, and that became the next round of features.

04 · Built

Built

Off the Shelf is a React 18 and TypeScript progressive web app, built with Vite and Tailwind on a Supabase backend and deployed on Vercel, so it installs to a phone's home screen. It was product-managed and specified conversationally, built autonomously by Claude Code, then given a distinct cool-violet visual redesign.

05 · Design process

Design process

Off the Shelf has been used on one real trip: I shopped, and the other member of the household answered questions from home. I screenshotted each blocker as it happened, then checked every one against the app's code. These design artifacts start from that trip. Anything resting on assumption rather than evidence carries an (A) label, and the labels stay until interviews with other households replace them.

Proto persona card for The Island Run Shopper, one member of a two-person household who shops several stores in one day, with The At-Home Decider as a secondary role. Context, behaviors, goals and frustrations, some backed by the real trip and the rest marked (A) as assumptions, with what would validate the persona.
Proto persona. Built from one real trip and its screenshots; every line marked (A) is an assumption until interviews replace it.
Six-stage journey map: list builds up, plan before leaving, first store, ask home, mid-trip, drive home. Rows for doing, thinking, feeling, pain points and opportunities.
Journey map. The journey breaks in the store, not before the trip: setup happened, but the list inside the app could not be trusted, and the notes app won. Open the image for full size.
User flow in three parts: getting a list in through paste import and a review step, planning and running a city run store by store, and asking the person at home a question with a photo.
User flow, verified against the app code. The gaps it shows: a store needed on every imported row, every imported item defaulting to keep cool, nothing typed surviving a switch to another app, and no push between the two phones. Open the image for full size.
06 · Outcome

Outcome

A list the shopper cannot trust is worse than a plain one.

  • Deployed and working, but not adopted. It has been used on one real trip and not since, and there is no usage metric.
  • The reason is specific: on that trip it lost to the notes app in the aisle. The imported list needed a store typed on every row, marked every item keep-cool, and dropped notes typed before they were sent.
  • The next iteration is scoped at trust in the list during the trip (import accuracy, sensible defaults, and drafts that survive leaving the app), not at more features.
07 · Screens

Screens

Two screens from Off the Shelf: the trip view with running spending totals, keep-cool tags, and a next-stop button, beside the city-run plan that sequences the stops
A city run in the app: the trip view with running totals, keep-cool tags, and the next-stop button, beside the plan that sequences the stops. Shown with seeded demo data.