A location-based anonymous matchmaking app for "missed connections"
Backtrack is a cross-platform mobile application for iOS and Android that enables anonymous "missed connection" style matchmaking tied to physical locations.
Have you ever noticed someone interesting at a coffee shop, gym, or bookstore but didn't have the chance to say hello? Backtrack creates a digital ledger for each location where you can leave an anonymous note describing that person - and if they're on the app, they might just find your message.
You see someone Create an avatar They browse the
interesting at a βββββΊ describing them βββββΊ location's ledger
physical location + leave a note & find your post
β β β
β β β
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββββββ βββββββββββββββββ
β π Visit β β π€ Build Avatar β β π Browse & β
β Location β β + Write Note β β Match β
βββββββββββββββ βββββββββββββββββββ βββββββββββββββββ
β
βΌ
βββββββββββββββββ
β π¬ Start β
β Anonymous β
β Chat β
βββββββββββββββββ
- Location Discovery - Find venues using Google Maps integration
- Selfie Verification - Take a photo to verify you were actually there
- Avatar Builder - Create a customizable Bitmoji-style avatar describing the person you noticed
- Anonymous Notes - Write a message about your missed connection
- Location-Based Browsing - Browse posts at specific venues
- Description Matching - Create your own avatar and get matched with posts describing you
- Anonymous Conversations - Connect through real-time messaging without revealing identities
| Feature | Description |
|---|---|
| Cross-Platform | Runs natively on both iOS and Android |
| Real-Time Chat | Instant messaging powered by Supabase Realtime |
| Privacy First | Anonymous interactions with no personal data exposed |
| Content Moderation | Reporting and blocking for a safe community |
| Secure Authentication | Sign up and login with email/password via Supabase Auth |
Coming soon - Screenshots will be added as the app is developed
Backtrack is built with modern, production-ready technologies designed for cross-platform mobile development.
| Technology | Purpose | Documentation |
|---|---|---|
| Expo SDK | React Native framework with managed workflow | Expo Docs |
| React Native | Cross-platform native mobile development | RN Docs |
| TypeScript | Type-safe JavaScript for reliability | TS Docs |
| Expo Router | File-based navigation for React Native | Router Docs |
| Zustand | Lightweight state management | Zustand Docs |
| Technology | Purpose | Documentation |
|---|---|---|
| Supabase | Backend-as-a-Service (BaaS) platform | Supabase Docs |
| PostgreSQL | Relational database (via Supabase) | PostgreSQL Docs |
| Supabase Auth | Authentication and user management | Auth Docs |
| Supabase Realtime | Real-time subscriptions for live chat | Realtime Docs |
| Supabase Storage | File storage for images and media | Storage Docs |
| Integration | Purpose | Documentation |
|---|---|---|
| Google Maps | Location discovery and venue selection | Maps SDK Docs |
| react-native-maps | Native map component for React Native | RN Maps Docs |
| Avataaars | Customizable avatar builder library | Avataaars Docs |
| Feature | Expo Module | Purpose |
|---|---|---|
| Camera | expo-camera |
Selfie verification for post creation |
| Image Picker | expo-image-picker |
Gallery access for profile images |
| Location | expo-location |
GPS for proximity-based features |
| SVG Rendering | react-native-svg |
Vector graphics for avatars |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mobile App β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Expo / React Native β β
β β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββ β β
β β β Screens β β Components β β Hooks β β Store β β β
β β β (Expo β β (UI, Map, β β (Auth, β β (Zustand) β β β
β β β Router) β β Avatar) β β Location) β β β β β
β β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Supabase Client β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Supabase Cloud β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ βββββββββββββββ β
β β Auth β β PostgreSQL β β Realtime β β Storage β β
β β (Users & β β (Database) β β (WebSocket) β β (Files) β β
β β Sessions) β β β β β β β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Services β
β ββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ β
β β Google Maps API β β Avataaars Library β β
β β (Venue Search & Display) β β (Avatar Customization) β β
β ββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Choice | Rationale |
|---|---|
| Expo | Simplifies React Native development with managed workflow, OTA updates, and easy deployment |
| TypeScript | Catches bugs at compile-time and improves code maintainability |
| Supabase | Open-source Firebase alternative with PostgreSQL, real-time, and auth out of the box |
| Google Maps | Industry-standard location services with excellent POI data |
| Avataaars | Privacy-preserving visual descriptions without requiring actual photos |
Before you begin, ensure you have the following installed on your development machine:
| Requirement | Minimum Version | Recommended | Check Command |
|---|---|---|---|
| Node.js | 18.x | 20.x LTS | node --version |
| npm | 9.x | 10.x | npm --version |
| Git | 2.x | Latest | git --version |
| Platform | Requirement | Notes |
|---|---|---|
| iOS | macOS + Xcode | Required for iOS simulator and builds |
| Android | Android Studio | Required for Android emulator and builds |
| Physical Device | Expo Go app | Scan QR code to run on device |
π‘ Tip: For the fastest setup, use the Expo Go app on your physical device - no simulator setup required!
Get up and running in minutes with these essential steps:
- Node.js 18.0.0 or higher (download)
- npm or pnpm package manager
- Git for version control
- Supabase account (sign up free)
- Google Cloud account with Maps API (get started)
- Clone the repository
git clone https://github.com/shortforge/backtrack.git
cd backtrack- Install dependencies
npm installThis installs all required dependencies including:
- React Native / Expo SDK
- Supabase client
- Navigation libraries
- Map and avatar components
- Set Up Environment Variables
Create a .env.local file in the project root:
# Copy the example file
cp .env.example .env.localThen add your API keys:
# Supabase Configuration
EXPO_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
# Google Maps Configuration
EXPO_PUBLIC_GOOGLE_MAPS_API_KEY=your-google-maps-api-keyFor detailed setup instructions, see our Contributing Guide.
- Start the Development Server
npx expo startThis will start the Expo development server and display a QR code.
- Run on Your Device or Simulator
| Method | Command/Action |
|---|---|
| Physical Device | Scan the QR code with Expo Go app |
| iOS Simulator | Press i in terminal (macOS only) |
| Android Emulator | Press a in terminal |
| Web Browser | Press w in terminal |
Here's a quick reference for common development commands:
# Start development server
npx expo start
# Start with tunnel (for devices on different networks)
npx expo start --tunnel
# Start with cache cleared
npx expo start --clear
# Run on iOS simulator
npx expo run:ios
# Run on Android emulator
npx expo run:android
# Install a new Expo-compatible package
npx expo install <package-name>
# Check for Expo SDK compatibility issues
npx expo-doctor
# Build for production (requires EAS)
npx eas build --platform allFor detailed setup instructions and guides, see:
-
Contributing Guide - Complete developer setup with step-by-step instructions for:
- Supabase project configuration
- Google Maps API setup
- Environment variables
- Development workflow
- Troubleshooting
-
Database Guide - Database setup and management:
- Schema overview
- Running migrations
- PostGIS configuration
- Row Level Security (RLS) policies
The project follows an Expo Router file-based routing pattern with organized folders for components, hooks, and utilities.
backtrack/
βββ app/ # π± Expo Router app directory (screens/routes)
β βββ (auth)/ # Authentication routes (login, signup)
β β βββ login.tsx
β β βββ signup.tsx
β β βββ _layout.tsx
β βββ (tabs)/ # Main tabbed navigation
β β βββ home.tsx # Home/Feed screen
β β βββ explore.tsx # Location exploration/map
β β βββ create.tsx # Create post screen
β β βββ messages.tsx # Conversations list
β β βββ profile.tsx # User profile
β β βββ _layout.tsx
β βββ chat/ # Chat screens
β β βββ [id].tsx # Dynamic chat view
β βββ post/ # Post detail screens
β β βββ [id].tsx # Dynamic post view
β βββ _layout.tsx # Root layout
β βββ index.tsx # Entry point
β
βββ components/ # π§© Reusable React components
β βββ ui/ # Generic UI components
β β βββ Button.tsx
β β βββ Input.tsx
β β βββ Card.tsx
β β βββ Avatar.tsx
β βββ avatar/ # Avataaars-related components
β β βββ AvatarBuilder.tsx
β β βββ AvatarPreview.tsx
β βββ map/ # Map-related components
β β βββ MapView.tsx
β β βββ LocationPicker.tsx
β βββ post/ # Post-related components
β β βββ PostCard.tsx
β β βββ PostForm.tsx
β βββ chat/ # Chat-related components
β βββ MessageBubble.tsx
β βββ ChatInput.tsx
β
βββ hooks/ # πͺ Custom React hooks
β βββ useAuth.ts # Authentication hook
β βββ useLocation.ts # Location services hook
β βββ usePosts.ts # Posts data hook
β βββ useChat.ts # Real-time chat hook
β βββ useProfile.ts # Profile management hook
β
βββ lib/ # π Core libraries and utilities
β βββ supabase.ts # Supabase client configuration
β βββ api/ # API functions
β β βββ auth.ts
β β βββ posts.ts
β β βββ messages.ts
β β βββ profiles.ts
β βββ utils/ # Utility functions
β βββ formatting.ts
β βββ validation.ts
β
βββ store/ # ποΈ State management (Zustand)
β βββ auth.ts # Auth state store
β βββ posts.ts # Posts state store
β βββ chat.ts # Chat state store
β βββ ui.ts # UI state store
β
βββ types/ # π TypeScript type definitions
β βββ index.ts # Shared types
β βββ database.ts # Database schema types
β βββ api.ts # API response types
β βββ ui.ts # Component prop types
β
βββ app.json # Expo configuration
βββ tsconfig.json # TypeScript configuration
βββ .env.example # Environment variable template
βββ .gitignore # Git ignore rules
βββ package.json # Project dependencies
βββ eas.json # EAS Build configuration
βββ CONTRIBUTING.md # Developer setup guide
βββ LICENSE # MIT License
Backtrack uses Vitest as its testing framework, providing fast, modern testing with excellent TypeScript support.
| Command | Description |
|---|---|
npm test |
Run all tests in watch mode |
npm run test:run |
Run all tests once |
npm run test:watch |
Run tests in watch mode (alias for npm test) |
npm run test:coverage |
Run tests with coverage report |
npm run test:e2e |
Run end-to-end tests |
npm run test:unit |
Run unit tests only |
npm run test:components |
Run component tests only |
Tests are organized in two locations:
backtrack/
βββ __tests__/ # Centralized test files
β βββ lib/ # Tests for library code
β βββ utils/
β βββ geo.test.ts # Example: geo utility tests
β
βββ components/ # Component tests (co-located)
β βββ chat/
β βββ __tests__/
β βββ ChatInput.test.tsx
β
βββ hooks/ # Hook tests (co-located)
βββ __tests__/
βββ useAuth.test.ts
Tests use Vitest's API which is compatible with Jest. Import test functions explicitly:
import { describe, it, expect, vi, beforeEach } from 'vitest'
describe('Feature Name', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should do something', () => {
expect(result).toBe(expected)
})
it('should mock dependencies', () => {
const mockFn = vi.fn().mockReturnValue('mocked')
expect(mockFn()).toBe('mocked')
})
})Use vi instead of jest for mocking:
| Jest | Vitest |
|---|---|
jest.fn() |
vi.fn() |
jest.mock('./module') |
vi.mock('./module') |
jest.spyOn(obj, 'method') |
vi.spyOn(obj, 'method') |
Tests automatically run in the appropriate environment based on file patterns:
| Pattern | Environment | Use Case |
|---|---|---|
components/**/*.test.tsx |
jsdom |
React component testing |
hooks/**/*.test.tsx |
jsdom |
React hook testing |
lib/**/*.test.ts |
node |
Utility/server-side testing |
*.happy.test.tsx |
happy-dom |
Performance-optimized DOM testing |
Generate coverage reports with:
npm run test:coverageCoverage reports are generated in multiple formats:
- Terminal: Summary displayed after tests
- HTML: Open
coverage/index.htmlfor detailed view - JSON: Machine-readable format for CI integration
Current coverage thresholds:
- Branches: 50%
- Functions: 50%
- Lines: 50%
- Statements: 50%
We welcome contributions! Please read our Contributing Guide for details on setting up your development environment and our coding standards.