YesTonite - Building a casual dating app for web and Android
A casual dating app for adults that drops matching altogether, built by techlead.fit for City Dev as one product on the web and on Android.
Part 1 of the YesTonite series. This is the overview; the deep dives are linked at the end.
Project snapshot
|
Field |
Detail |
|---|---|
|
Project |
YesTonite |
|
Type |
Client project · consumer web app and Android app |
|
Client |
City Dev, the Netherlands (operator of YesTonite) |
|
Industry |
Online dating and social discovery (18+) |
|
Built |
2026 |
|
Timeline |
About one week to the live web app · Android in Google Play closed testing from mid-October 2026 |
|
Started |
6 October 2026 |
|
Team |
1 CTO, 1 developer, 1 designer |
|
Delivery |
Built end to end by techlead.fit: product decisions, architecture, web, Android, backend, payments, release |
|
Status |
Web app live at yestonite.com · Android app in Google Play closed testing, public launch planned end of October 2026 · iPhone app planned for mid to end of November 2026 |
|
Stack |
Next.js 16 · Expo SDK 57 (React Native) · Directus 12 · PostgreSQL · AWS (Lightsail, S3, SES) · Vercel · Stripe · Google Play Billing · Firebase Cloud Messaging · GitHub Actions |
The situation
Most dating apps are built around the match. You swipe, the other person swipes, and only when both say yes can anyone talk.
That model works for finding a long-term partner. It works less well for a simpler question: who nearby wants to go out tonight?
City Dev came to us with that question and a clear product idea. No matching. You see a face, an age, a distance and what someone is in the mood for tonight. You say something, and the chat opens for both of you.
The brief was not a prototype. It was a product people could use: on the web first, then on Android, then on iPhone, in many languages and with fair prices in many countries.
No matches. Just people.
The challenge
Removing the match removes a gate. That makes the product simpler for members and harder for the people who build it.
In a matching app, the match is also a safety filter. Without it, the product needs other ways to keep unwanted contact down, keep minors out, and act fast on reports.
There were three more constraints:
-
One product on two platforms. The web app and the Android app had to behave the same and say the same things, down to the wording of an error.
-
International from day one. A dating app that only speaks English and charges US prices everywhere does not fit most of the world.
-
Payment and store policies. Dating is a restricted category for payment providers and app stores. Both review it closely.
Decisions before code
Most of the important work happened before the first screen was built.
No matching, but limits on new chats. Anyone can start a chat, but each member has a daily allowance of new chats. Replies in open chats are always free. This keeps the feed open without turning it into a spam channel.
Names private until shared. Profiles show a photo, an age, a sign and an interest for tonight. A member's first name appears in a chat only when they choose to share it.
Free to use, with optional extras. Joining, browsing, chatting and events are free. Paid extras are small and optional: chat packs, 24 hours of unlimited new chats, and a weekly or monthly plan to hide your profile for a while. No subscription is needed to meet anyone.
One backend as the single source of truth. Prices, texts, rules and limits live in one place. The web app and the Android app read them; neither decides them.
Web first, then Android, then iPhone. The web app could go live without store review, so it went first. Android followed through Google Play testing. iPhone is planned after Android.
Data in the EU. The backend, database and file storage run in Frankfurt.
Safety rules on the server. Age, e-mail confirmation and sign-in checks are enforced by the backend, not by the screens. A modified client cannot skip them.
What YesTonite does
1. See who is nearby
The feed shows people nearby: one photo, an age, an approximate distance, a sign and what they want to do tonight. Members can sort by who is online now or who is out tonight.
2. Say you are out tonight
An "Out tonight" status tells others you are open to meeting today. It shows as a green dot on your tile.
3. One message opens the chat
There is no waiting to be liked back. The first message opens the chat for both people. Photos shared in chats stay between the two of them.
4. Events
Members host and join events in real places and online: open ones you can join right away, and invite-only ones where you request a spot. Spots can be balanced per sign, there are waitlists, and the address unlocks only for people who are in.
5. Stay in control
Block or report anyone in two taps. Hide your profile for a while. Only an approximate area is used, never an exact location.
The build
The team was one CTO, one developer and one designer. The designer owned the brand and the screens. The CTO owned the product decisions and the architecture. Development covered the backend, the web app and the Android app.
Backend. Directus 12 on PostgreSQL, with a custom extension for everything that is specific to YesTonite: the feed, chats, events, payments, verification, moderation and pricing. Directus Studio doubles as the admin and moderation tool, so City Dev can change prices, texts and settings without a developer. It runs in Docker on AWS Lightsail in Frankfurt, with managed PostgreSQL and S3 file storage.
Web app. Next.js 16 on Vercel. The browser never talks to the backend directly. A server-side layer (a backend for frontend) forwards only an allow-listed set of calls, each with its own validation. That keeps the backend private and the attack surface small.
Android app. Expo SDK 57 with React Native. It uses the same backend and the same texts as the web app. The locale files are written once for the app and synced to the web, so both platforms always say the same thing in every language.
Payments. Stripe Checkout on the web, Google Play Billing in the app. The backend computes every price; the client cannot send one. A script keeps the Google Play prices equal to the website prices per country.
Real time. Chats update over WebSockets. Push notifications go through Firebase Cloud Messaging on Android and Web Push in the browser.
Languages. The apps ship in 44 languages, the backend in 45, and the blog in 43.
Release pipeline. Every backend push is checked and deployed by GitHub Actions. The schema is applied automatically, migrations run, health is checked, and a failed deploy rolls back by itself.
Growth. A partner (affiliate) program with a fixed payout per new customer per country, tracking links and server-to-server postbacks for networks. Analytics with consent. A blog for search.
Testing and validation
Each round of work came with its own tests.
-
An end-to-end smoke test drives the backend over HTTP and WebSockets and must pass in full.
-
Browser tests run the web app in a real headless Chrome for every feature round: navigation, chats, push, payments and languages.
-
A language check makes sure every text exists in every language, so no screen falls back to English by accident.
-
Payments were tested against Stripe test mode and Google Play license testers.
-
The Android app is in Google Play closed testing with real testers before the public launch.
Outside the code, the product passed two reviews that every dating product meets: Stripe's review of restricted businesses, and Google Play's policies for dating apps, including the child safety declaration.
Outcome
YesTonite is live on the web at yestonite.com, in 44 languages, with prices set for 63 countries.
The Android app is in Google Play closed testing. The public Android launch is planned for the end of October 2026. The iPhone app follows, planned for mid to end of November 2026.
City Dev runs the product day to day from Directus Studio: prices, texts, moderation, maintenance mode and a status dashboard, without needing a developer for routine changes.
What we learned
Removing a feature can add work. Dropping the match made the product simpler to explain and simpler to use, but it moved responsibility to the system: limits on new chats, server-side age checks, fast reporting and moderation.
Parity has to be designed, not hoped for. Shared locale files and one backend that owns every rule did more for consistency between web and Android than any amount of manual checking.
Compliance is product work. Stripe and Google Play both asked detailed questions about a dating app. Having written protocols for age, reports and law enforcement made those reviews a matter of answering, not scrambling.
Going web first paid off. The web app was live and learning from real use while the Android app went through store testing.
Why this is a techlead.fit case study
YesTonite is a client project, and it shows the full path we take with clients.
We started from the product question, not the stack. We made the hard decisions before development: no matching, private names, free core, one source of truth, web first. We built only what the product needed, on technology a small team can run. And we prepared the parts that usually surprise founders late: payment reviews, store policies, regional pricing and operations.
Start with the product.
Decide what actually needs to be built.
Keep one source of truth.
Validate with real users.
Then scale to more platforms and markets.
The YesTonite series
-
Part 1: YesTonite - Building a casual dating app for web and Android (this post)
-
Part 2: Global from day one: 44 languages and regional pricing in 63 countries
-
Part 6: A growth engine without an ad budget, and the first round
Looking for a technical partner for your app?
If you have a consumer product idea and need it on the web and in the app stores, the difficult part is often deciding what to build first and what can wait.
At techlead.fit, we turn an early product idea into a technical plan, make the key decisions before development, and build the first version with a small senior team.
Relevant services: CTO Sprint · MVP Build