Cairn — Leave a Little Wonder
Leave a memory somewhere. Find memories left by other people. The catch: you have to actually be there to see them.
💡 Inspiration
Cairns are stacks of stones that have traditionally been used by hikers and travelers as markers along trails. They tell you that someone has been there before, or that you're heading in the right direction.
We liked that idea and wanted to apply it to digital memories.
Instead of posting a photo to a feed where anyone can see it from anywhere, Cairn ties a memory to a real location. If someone leaves a cairn at a viewpoint, street, trail, or any other place, you have to physically go there to discover it.
The goal is simple: give people a reason to explore places and leave something behind for the next person.
🪨 What Cairn Does
Cairn is a location-based app where people can leave and discover digital memories tied to real-world locations.
🌍 Explore
Cairns are shown on an interactive globe and map. You can see where they exist, but their contents remain hidden until you get close to their location.
📡 Find
When you get close to a cairn, the app switches to a proximity radar with directional and distance information. This helps you find the exact location instead of simply showing a pin on a map.
🔐 Physical Unlocking
A cairn can only be collected when you're physically close to it — currently around 15 meters.
The distance check happens on the server using PostGIS rather than trusting the phone to decide whether a cairn can be collected.
📜 Memories
Once collected, a cairn can contain photos, videos, and notes left by previous people.
Entries are kept as a history rather than being overwritten, so you can see what different people added as the cairn moved between locations.
🎒 Carry & Redrop
Some cairns can be moved.
After finding one, you can carry it with you and drop it somewhere else. You can also add your own entry before passing it on.
This means a single cairn can gradually build a history across different places.
💎 Pebbles
Cairn has an in-app currency called Pebbles. They can be earned through exploration and used to create different types of cairns.
🛠️ How We Built It
Cairn is built with Flutter on the client and Supabase/PostgreSQL on the backend.
📱 Mobile App
- Flutter + Dart for the Android and iOS application.
- Riverpod for state management.
- GoRouter for navigation and deep links.
- Mapbox for the main map.
- Flutter Earth Globe for the 3D globe view.
- Geolocator + Flutter Compass for location, heading, and proximity features.
- Camera for capturing photos and videos directly inside the app.
The app uses the phone's location and compass data continuously while the user is searching for a nearby cairn.
🗄️ Backend
The backend uses Supabase, PostgreSQL, and PostGIS.
Cairn locations are stored as geographic points using geography(Point, 4326), with spatial indexes for location queries.
The client does not directly change important cairn state. Actions such as collecting, moving, redropping, and spending Pebbles go through PostgreSQL functions.
For example:
collect_cairn()redrop_cairn()spend_pebbles()
This also lets the database handle cases where multiple people reach the same cairn at roughly the same time.
💳 Payments
RevenueCat handles the app's subscriptions and in-app purchases.
It is used for:
- Pebble packs
- Explorer memberships
- Purchase verification
- Entitlements
- Restoring purchases
- Cross-platform subscription management
🧮 Location & Distance
One of the harder parts of Cairn is deciding whether someone is actually close enough to collect a cairn.
GPS isn't perfectly accurate, especially around buildings, trees, and other obstacles.
The backend calculates the distance between the user's reported position and the cairn using geographic coordinates and PostGIS.
A collection is allowed when the calculated distance falls within the discovery radius, while also taking the device's reported GPS accuracy into account.
The current discovery radius is approximately 15 meters.
This logic lives on the server instead of the Flutter client, so the app cannot simply tell the backend that a user is standing next to a cairn when they aren't.
🧗 Challenges
1. GPS Accuracy
GPS accuracy can vary considerably depending on where you are.
During testing, we found that a strict distance threshold could make some cairns difficult to collect, particularly near buildings and under heavy tree cover.
We adjusted the location checks to account for the device's reported accuracy while still keeping limits on how much that accuracy can affect the result.
2. Two People Finding the Same Cairn
A cairn can potentially be discovered by two people at almost the same time.
To handle this, collection is performed inside a database transaction using row-level locking.
The first successful transaction collects the cairn. A second request arriving at the same time sees that it has already been collected and fails cleanly.
3. Keeping Cairn History
Cairns aren't just single records that get updated whenever someone interacts with them.
The database separates the cairn itself from its entries and locations. This allows us to keep track of what was added and where the cairn has been over time.
Old entries aren't edited when someone adds a new one.
4. Handling Purchases
In-app purchases can be sent more than once because of retries, connection problems, or webhook behaviour.
We use a transaction ledger with unique RevenueCat transaction IDs so that the same purchase cannot grant Pebbles twice.
🏆 What We Built
Some parts of Cairn that we're particularly happy with:
- A complete loop from creating → placing → discovering → collecting → moving → redropping a cairn.
- Real GPS-based discovery instead of simply tapping a marker on a map.
- A map and globe interface for exploring cairns around the world.
- An append-only history for cairn entries.
- Server-side location and transaction handling.
- Cross-platform purchases and subscriptions through RevenueCat.
- A visual style inspired by maps, field guides, and physical stone cairns.
Most importantly, the core experience works outside the simulator. Cairns can be placed and discovered in real locations using the phone's GPS.
📚 What We Learned
Building Cairn taught us that location-based apps have a different set of problems from normal social apps.
GPS isn't reliable enough to treat a location as an exact point, and small delays in location updates can make a noticeable difference when someone is trying to find something.
We also found that the interface needs to give the user enough information to understand where to go without immediately giving away the exact location.
On the backend, putting important state changes in the database made the rest of the application much easier to reason about. The client mainly asks the server to perform an action, and the server decides whether that action is valid.
RevenueCat also removed a lot of the complexity around managing purchases and subscriptions across Android and iOS.
🔭 What's Next
Some of the features we're considering for future versions:
- Maps integration — Send a cairn's location directly to Google Maps, Apple Maps, or other navigation apps.
- Audio memories — Let people leave short audio recordings at locations.
- Expedition trails — Groups of cairns that form a route or exploration trail.
- AR — Use the camera to show a cairn at its real-world location.
- More cairn types — Different ways of creating and interacting with memories.
The basic idea will stay the same: you have to go there to find it.
Log in or sign up for Devpost to join the conversation.