Skip to content

SOCIAL PLATFORM · iOS & ANDROID

Locava

Locava is a vertical feed of real places posted by real people, not tour guides. You see how far each spot is from you, filter by what you are actually in the mood for, save places into collections, and go. I built it end to end and took it through launch.

View on the App Store
Two iPhones showing a Locava post and a user profile
10,000+
organic users, zero paid acquisition
~50%
weekly retention at peak
8,000+
places posted by users
742k
lines of TypeScript across the monorepo

User, retention and post figures are measured by Judson from Locava’s own instrumentation and are current to June 2026; retention is a peak figure from autumn 2025. The line count is reproducible from the repositories. None of these have been audited by an outside party, and the publications listed below covered the product without verifying them.

FEATURE BY FEATURE

What Locava actually does

The Locava map, showing photo pins across a region with activity filters and a spot count

01

Map discovery

Every post is a pin with its own photograph, so the map reads as places rather than dots. Filter chips narrow by activity, the counter tells you how much is actually out there, and current conditions sit in the corner because weather decides most of these trips.

BUILT WITH

@rnmapbox/maps on device, with geo queries served from Firestore behind composite indexes and cached in Redis so panning does not become a billing event.

The Locava search screen with friend avatars and curated mixes for hiking, park, beach and cafe

02

Mixes for you

Instead of one algorithmic feed, discovery is broken into named mixes: Hiking, Park, Beach, Cafe, Sunset, View, plus a nearby mix and a row of what friends are posting. It gives people a reason to browse when they do not have a specific search in mind.

BUILT WITH

On-device Google ML Kit image labelling tags media as it is created, and a 768-dimensional vector index over those embeddings powers retrieval per mix.

A Locava post showing a swimming hole with a Visit now, 20 minute button

03

The post, and how far away it is

A post is full-bleed media with the caption set over it, and the primary action is not a like. It is Visit now, with the travel time already computed. That single label is the product thesis: a place you cannot reach is not a recommendation.

BUILT WITH

expo-image and expo-av for media, with travel time resolved against the viewer's location and the palette pulled from the image so the card has colour before the photo decodes.

The Locava directions panel routing to a marked location, with transport modes and a 20 minute ETA

04

Directions to the exact spot

Most of these places do not have an address. A swimming hole is a pull-off and a path; a viewpoint is a bend in a dirt road. So the destination is the marked location itself rather than the nearest thing with a street number, and you get the route, the travel mode and the ETA to that point.

BUILT WITH

The coordinates travel on the post, so routing runs against the pin somebody actually dropped instead of a geocoded guess at the closest address.

A Locava direct message thread with a shared video post between two friends

05

Sharing is the loop

Nobody goes anywhere alone, so a post shared into a DM renders as the post, playable, tappable, with its distance intact, rather than as a dead link. Most of Locava's organic growth runs through this screen.

BUILT WITH

Firestore listeners for live threads, expo-notifications for push, and pre-generated video thumbnails so a shared clip has a poster frame immediately.

A Locava profile showing follower counts and a grid of posted places

06

Profiles and collections

A profile is a record of where someone has actually been. Four views: grid, collections, saved and a personal map, so the same set of places can be browsed as a portfolio, a wishlist or a territory.

BUILT WITH

Fastify REST endpoints typed by the shared @locava/contracts Zod schemas, with read paths cached in Redis and writes fanned out through Cloud Tasks.

The Locava web app on a laptop, showing a map beside a grid of places

07

The web surface

The same places, on a desktop, for planning something longer than an afternoon, plus the admin and marketing surfaces the business needs to run.

BUILT WITH

Next.js talking to the same Fastify backend through the same contracts package, with the Firebase client SDK used directly only where it earns it.

01The problem

Finding somewhere genuinely worth going takes an hour of cross-referencing forums, Google Maps and a friend's half-remembered recommendation. And when you finally find it, it turns out to be four hours away.

Locava collapses that into one feed. Every post is a real place with a real distance attached, so the first question, can I actually get there today, is answered before you decide whether you care.

02How the system is shaped

Four codebases, deliberately separated. The mobile client is Expo and React Native with Expo Router. The backend is a Fastify service in TypeScript. The web surface is Next.js. And between them sits @locava/contracts, a package of Zod schemas that is the single source of truth for every request, response and entity shape.

That contracts package is the decision I would defend hardest. It means a change to an API shape is a change to a shared, typed, versioned artefact rather than a local edit that quietly breaks a client. Contract changes get treated like changes to a public API, because that is what they are.

Firestore and Firebase Storage are the source of truth, but nothing outside the backend's repository layer is allowed to touch them. Redis and an in-memory tier sit in front. That boundary is what makes it possible to change storage decisions later without rewriting two clients.

03Making the feed feel instant

The whole product lives or dies on one scroll. There are two feeds, Explore and Following, each with cursor pagination, in-flight request cancellation when you switch tabs, and guards against duplicate pagination when a fast scroll fires two loads at once.

Media is the expensive part, so it gets its own pipeline: sharp for server-side processing, presigned multipart uploads straight to S3-compatible storage, video thumbnails generated ahead of time, and dominant-colour extraction so a card has something to show in the moment before its image decodes.

04Instrument first, guess later

Logging, crash tracking, OpenTelemetry traces and usage dashboards went in before there was a launch date, with BigQuery behind them as the warehouse. That ordering is the single most useful decision I made. It turned roadmap arguments into questions with answers, and it is how one person debugs production without a team to page.

The test suite is the other half of that. 777 test files across the mobile client and the backend, which is the only reason I could keep shipping features while supporting live users alone.

05Where it got to

10,000+ organic users and 8,000+ user-generated posts with no paid acquisition, sustaining roughly 50% weekly retention. That traction is what closed the seed round, and the team grew to eight, two full-time engineers and six interns, with sprint planning and code review.

06Built with

  • TypeScript
  • React Native
  • Expo Router
  • Fastify
  • Next.js
  • Zod
  • Firestore
  • Redis
  • Google Cloud Run
  • Cloud Tasks
  • BigQuery
  • Mapbox
  • ML Kit
  • sharp
  • OpenTelemetry
A Locava post showing a hiker on a snowy ridge, captioned “I may have lied”
A Locava post about the abandoned Gath Family Mansion
A Locava post: a drone shot over an open field at dusk, captioned “easy livin”
The Locava comments sheet open on a post, with an aerial of a river town behind it

More work