A full stack dog dating app — because your dog deserves a playdate too.
🌐 Live Demo: https://off-leash.onrender.com
Off Leash started as an Android mobile app I built during my college capstone project. Years later, I rebuilt it from scratch as a modern full stack web application — applying everything I've learned about software engineering to bring the original vision to life.
The concept: dog owners at a park can discover other nearby dogs, swipe to connect, and when two dogs mutually like each other, it's a match — giving the humans a reason to meet too.
- 🔐 Authentication — Secure register and login with JWT tokens and bcrypt password hashing
- 🐶 Dog profiles — Create a detailed profile for your dog including breed, age, size, energy level, temperament, and bio
- 📍 Geolocation — Browser GPS captures your location when creating a profile, stored using PostGIS geography columns
- 🗺️ Nearby discovery — PostGIS radius queries find dogs within 10 miles of your current location
- 👍 Swipe system — Like or pass on nearby dogs; swiped dogs never appear again
- 💥 Matching algorithm — Mutual likes automatically create a match in real time
- 💚 Matches page — View all your matched dogs with match date
- React + Vite — fast, modern UI
- Tailwind CSS — utility-first styling
- React Router — client-side navigation
- Axios — API communication
- Node.js + Express — REST API
- PostgreSQL + PostGIS — relational database with geospatial queries
- Supabase — cloud-hosted PostgreSQL with PostGIS pre-installed
- JWT — stateless authentication
- bcryptjs — password hashing
- Render.com — backend API and frontend static site
- Supabase — production database
users -- owner accounts (id, email, password_hash, name)
dogs -- dog profiles (id, owner_id, name, breed, size, energy_level, location)
swipes -- like/pass interactions between dogs
matches -- mutual likes that created a matchThe location column uses PostGIS GEOGRAPHY(POINT, 4326) for accurate distance calculations.
PostGIS geolocation query — finds dogs within 10 miles and calculates exact distance:
SELECT d.name,
ROUND((ST_Distance(d.location::geography, md.location::geography) / 1609.34)::numeric, 1) AS miles_away
FROM dogs d
CROSS JOIN dogs md
WHERE md.id = $1
AND ST_DWithin(d.location::geography, md.location::geography, 16093)Matching algorithm — checks for mutual likes on every swipe and creates a match instantly:
const mutualLike = await getPool().query(
`SELECT id FROM swipes
WHERE swiper_dog_id = $1 AND swiped_dog_id = $2 AND direction = 'like'`,
[swiped_dog_id, swiperDogId]
)
if (mutualLike.rows.length > 0) {
// It's a match!
}- Node.js v18+
- A Supabase project with PostGIS enabled
# Clone the repo
git clone https://github.com/himynameismoose/off-leash.git
cd off-leash
# Install server dependencies
cd server
npm install
# Create server/.env
PORT=3001
DATABASE_URL=your_supabase_connection_string
JWT_SECRET=your_jwt_secret
# Start the server
npm start
# In a new terminal, install client dependencies
cd client
npm install
# Start the client
npm run devVisit http://localhost:5173 to use the app.
off-leash/
├── client/ # React + Vite frontend
│ └── src/
│ ├── pages/ # Login, Signup, Dashboard, Discovery, Matches
│ ├── api.js # Centralized Axios config
│ └── main.jsx # App entry point
└── server/ # Node.js + Express backend
├── routes/
│ ├── auth.js # Register + login
│ ├── dogs.js # Dog profiles + nearby + matches
│ └── swipes.js # Swipe recording + match detection
└── index.js # Express server setup
This app started as an Android Studio project during my college capstone — an MVP I was proud of but never got to fully finish. After gaining professional experience as a software engineer at Wells Fargo and Topgolf, I rebuilt it from the ground up as a full stack web app, applying real-world patterns: JWT auth, PostGIS geolocation, cloud deployment, and a matching algorithm.
Mershelle — @himynameismoose