ShiftPass is a two-sided shift marketplace for restaurants: post an open shift, see vetted workers near you on a live map, and fill it fast. AppMakers USA engineered the geography and the map underneath it — and still ships it.
A restaurant with a hole in tonight's rota, and a vetted pro looking for the next gig nearby — the same marketplace, seen from two directions. Switch sides to see the product each one uses.
Every listing is a join: job → business → address → application status, filtered by real distance.
Every screen is two problems at once: a "near me" search and a live marketplace.
Each list query is part radius/bounding-box filter (who is near this point) and part marketplace state (job status, application history, proposals). The relational joins — job to business to address to application status — dominate the workload, and we needed real Earth-distance math, not flat-plane latitude/longitude.
So we stored each address as a PostGIS geography point on Postgres and used ST_DWithin for the "near me" radius and ST_MakeEnvelope / ST_Within for the map's pan bounding box — a single query powers both the nearby list and the live map view.
We chose Kysely over Prisma because the geo predicates only express well in raw SQL, and Kysely lets you drop into a typed SQL block without losing type safety on the rest of the query. We passed over MongoDB's $near and managed search services like Algolia or Elastic, because the relational joins dominate and we wanted true geography, not approximation. Every list is cursor-based, not offset, because new jobs and applications are inserted constantly — and offset pagination silently skips and duplicates rows while a user scrolls.
Every time the list refetched, it produced a new jobs array reference. Mapbox saw a "new" dataset, re-clustered the GeoJSON, and the markers visibly blinked while the user was moving across the map. The cruelest part: it only reproduced while panning, which made it embarrassingly easy to miss in QA.
No single change fixed it. It took four layers working together.
Keep the data alive. placeholderData: (prev) => prev on the infinite query so a refetch never fell back to an empty state.
Update on IDs, not references. A separate displayJobs slice that only changes when the set of job IDs actually changes, not when the array reference does.
Memoize the map. Custom memo comparators on the Map and Markers components, keyed on the joined IDs.
Stabilize the callbacks. Ref-wrapped onPress handlers so a changing parent callback couldn't bust the memoization.
None of the four alone was enough. Together, the markers stopped blinking and the map stayed steady while users panned across the city.
Building a two-sided marketplace that has to feel instant on a map?
Get a Free Project Estimate →AppMakers builds native for iOS and Android, with the geo and realtime backends behind them.
Shipped to iOS and Android, 5.0★ across its App Store ratings — a two-sided marketplace real restaurants and workers use.
The marker-flicker that only showed while panning is gone; the map holds steady across constant refetches as users move across the city.
ShiftPass launched in late 2025 and keeps moving — latest release June 2026. A marketplace is never "done," and that's exactly the work we stay for.
Location-first products live or die on the details — real geography, smooth maps, marketplace state that stays correct under load. We build for that, and we stay through it, the way we did for ShiftPass.
Get a Free Project Estimate →