Inspiration

In real life people constantly need a temporary partner for one specific thing: a coffee, a tennis match, a trip, a watch party, trying a new restaurant. Today that happens through messy WhatsApp groups, Reddit threads, and awkwardly asking around. Dating apps are profile-first. Meetup is group-first. Both make you browse people and hope. We wanted the opposite: plan-first. You post what you want to do, and the right person comes to you.

What it does

LoopIn matches people on intent, not photos. You post a "loop" (coffee, sports, travel, or anything), and a config-driven engine finds compatible people and is honest about fit — it tells you who to skip and why. You browse matches as a calm swipe deck (right to loop in, left to pass, up to save, down to skip), tap any card for the full compatibility breakdown, and open a person's profile to see all their loops. When you connect, we hand you a grounded icebreaker built from what you actually have in common.

The honesty layer is the differentiator: most apps hide bad matches to maximize swipes; LoopIn shows a "we'd skip this one" card with concrete reasons (budget mismatch, skill gap, different pace). That builds trust, which is also how it monetizes: verification and premium connections.

How we built it

  • Frontend / hosting: Next.js 16 (App Router) on Vercel.
  • Database: Amazon Aurora PostgreSQL + pgvector. The DB isn't just storage, it is the matching engine: hard constraints as SQL WHERE, soft ranking over an attributes JSONB column, and vibe similarity via pgvector cosine (embedding <=> query).
  • The engine: every category is a declarative config object; the engine is generic and never names a category, so "pickleball", "roommate", or "F1 watch party" is a new config, not new code. Three layers: hard filters, transparent weighted score, conflict/honesty rules.
  • AI: Anthropic Claude turns a one-sentence plan into a structured card and phrases icebreakers, but the database decides; the LLM only translates the math into English.
  • Dev experience: the same SQL runs on embedded PGlite locally and Aurora in production; only the connection string changes.

Challenges we ran into

Making "explainable compatibility" real instead of a black box (solved with a transparent three-layer engine), keeping a data-dense matching UI calm (a low-contrast warm theme and a one-card swipe deck), and a turnkey local-to-Aurora story (a dual-driver data layer with an idempotent schema that self-initializes on first connect).

Accomplishments that we're proud of

An honest matching engine that will tell you not to meet someone; one engine across coffee, sports, travel, and a freeform "anything"; and a full journey from posting a plan to swiping image cards to viewing a profile.

What we learned

The hard part of matching isn't the swipe, it's trust and explainability. Showing why a match works (and when it won't) is worth more than another recommendation.

What's next for LoopIn

Real ID verification, persistent identity and "my loops", saved/passed lists, real-time chat after connecting, a refine/filter bar, and swapping the local embedding for a production embeddings model behind the same pgvector query.

Built With

Share this project:

Updates