Family Nearby: an Android Family-Location App on a Go Backend, Built Solo
My own product. A family location-sharing app shaped by 12,180 competitor reviews, with a Kotlin/Compose Android app, a single Go server with a live WebSocket map, and tag-to-production CI/CD with automatic rollback. Built with Claude Code and now in Google Play review.
- Role:
- Founder and sole engineer: product research, Android app, Go server, infrastructure, CI/CD, website
- Period:
- Sep – Oct 2026, own product (in Google Play review)
- Go
- Kotlin
- Jetpack Compose
- PostgreSQL + TimescaleDB
- WebSocket
- Protobuf
- Mapbox
- Cloudflare
- GitHub Actions
- Docker
- Caddy
The brief
Families use location apps every day, and they complain about the same things: stale locations, late alerts, battery drain and buggy updates. Before writing code, I read the market leader's reviews, 12,180 of them, and turned each top complaint into a target I could measure:
- Fresh location within 60 seconds of a refresh.
- A place alert within 30 seconds of a confirmed arrival.
- The map always shows how old each location is.






Architecture
Key decisions
- One server, on purpose. One Go binary runs the API, the live WebSocket hub and the background jobs, next to Postgres on one VPS behind Cloudflare. That handles about 10,000 users for a small monthly bill. Redis and a message bus wait until they are needed.
- A live map that feels live. Positions, speed and heading stream to the map over WebSocket, in compact Protobuf. The heading draws the direction cone under a moving member's pin.
- Battery as a feature. The location engine combines fused location, activity detection and geofences, and backs off when someone is still. Bad fixes are dropped on the phone.
- Shared rules, native UI. Place and alert logic lives in a UI-free Kotlin core, ready for a future iOS app.
- Privacy by default. Short retention, full export and delete, quiet hours, and no ads.
CI/CD: a git tag is a release
- Every push:
go vet, staticcheck and the full test suite, with real Postgres in Testcontainers. - Push a
v*tag: tests run again, then a Docker image goes to GHCR and deploys to the VPS. - Health check: the server must report "ok" and the new version through Caddy. If not, it rolls back to the previous release automatically.
- Safe migrations: expand/contract only, so a rollback never has to undo the database.
Behind it: nightly encrypted backups to Cloudflare R2, a tested restore, fail2ban and SSH-key-only access.
Built with Claude Code
Claude Code was my engineering team, and I made the calls. Every milestone ran the same loop:
- Spec: what to build and why.
- Plan: tasks, each with a "done when" check.
- Build: tests first.
- Review: an independent code review before merge.
The specs and plans live in the repo next to the code. That loop is how a solo build reached 4,300+ tests and a store-ready release in about two weeks.
What I'd do differently
Start the Play Store listing, privacy pages and data-safety form in week one, not at the end. Store review sits on the critical path, and it doesn't care how good the code is.