Short answer
RaftLabs built IntroJoy, a professional introduction web app that replaces the back-and-forth email coordination required for warm introductions with a structured double opt-in flow. The connector drafts the introduction once, both parties confirm via email, and the connection is made without further coordination. IntroJoy reached 10,000 users in 6 months, earned a 4.2/5 rating on Product Hunt, and expanded active users' professional networks by 20% (client-reported). Built in 12 weeks using React, Node.js, PostgreSQL, and AWS SES for high-deliverability email dispatch.
The situation
Making a warm professional introduction involves more coordination than it should. The connector emails person A to ask if they want to be connected, waits for a reply, emails person B for the same, waits again, then writes the mutual introduction email, only to be copied on the back-and-forth that follows while hoping neither party feels their inbox was disrupted without permission.
The problem is consent and coordination happening manually when both could be handled by a structured tool. IntroJoy is that tool. We built it as a web app where the connector drafts the introduction once, both parties receive an opt-in confirmation email, and the connection is made only when both agree. The client reported that 10,000 users joined in the first six months, and active users expanded their professional networks by 20%.
The asymmetry is the point: an email that takes the connector 30 seconds to write commits someone else's time. Mary is supposed to get coffee with Jack because Joe thought it would be a good idea. And if Mary ignores the intro, she looks like a jerk. Skipping consent is the fastest way to burn social capital. IntroJoy makes the 30-second ask stop committing someone else's afternoon.

Engagement
The IntroJoy engagement
- Product
- IntroJoy, a web app for making professional introductions with a double opt-in flow
- What we built
- One-draft introductions: the connector writes once, both parties confirm by email, and the connection is made only when both agree. Templates, status tracking, and a full introduction state machine
- Stack
- Web app, email state machine, customizable templates, status dashboard
- Status
- Live. The client reported 10,000 users in the first six months and a 4.2 out of 5 Product Hunt rating
Before and after
What changed
- Making a warm introduction required multiple back-and-forth emails to confirm consent from both parties before the actual introduction could be sent
- Connectors tracked the status of each introduction manually, following up, resending, and chasing replies across an unstructured email thread
- There was no guarantee both parties had agreed to the connection before contact details were shared, leading to introductions that landed without consent
- The quality of the introduction email varied with how much time the connector had; no template or preview existed to standardize the format
- Once the introduction was made, the connector had no visibility into whether the connection progressed or went unanswered
- The connector drafts the introduction once; both parties receive a confirmation email and accept or decline independently, with no further coordination required from the connector
- Introduction status (pending, one accepted, connected, declined, or expired) is visible from the dashboard without the connector tracking anything manually
- Consent is confirmed before any contact details are shared; neither party receives the other's information until both have accepted
- Customizable email templates allow connectors to maintain a consistent, personal tone without rewriting from scratch for every introduction
- Connected introductions and their status are logged in the platform so connectors can see the outcome of every introduction they have made
What we had to solve
Building a double opt-in flow that felt like a warm introduction, not a compliance form
The entire value of a warm introduction is that it carries the connector's credibility and feels personal. An automated flow that reads like a system email undermines that credibility immediately. The design challenge was making the confirmation email feel like it came from a person (using the connector's own name, their drafted introduction text, and the context they provided) while the underlying workflow was fully automated. Getting that balance right between automation and apparent personalization was the UX and copywriting challenge at the core of the product.
Managing the state machine for introductions reliably across multiple email clients
An introduction can be in a dozen states: draft, sent to party A, party A accepted, sent to party B, both accepted, declined by either party, expired after no response, re-sent after reminder. Each state transition was triggered by email confirmation links that needed to work across Gmail, Outlook, and other clients without link-click tracking failures. Building a state machine that handled retries, reminder scheduling, expiry logic, and edge cases (one party accepts before the other has opened the email, a confirmation link clicked twice) was the backend engineering challenge.
Proof
What the client reported, and what this page can't claim
Adoption and rating figures reported by the client. These are operator reports, not independently audited measurements.
| Result | What changed | Period or context | Evidence and limitation |
|---|---|---|---|
| Adoption | 10,000 users in the first six months | The connector drafts the introduction once; both parties accept or decline independently with no further coordination required | Client-reported |
| Network growth | Active users expanded their professional networks by 20% | Consent confirmed before any contact details are shared; neither party receives the other's information until both have accepted | Client-reported |
| Public reception | 4.2 out of 5 rating on Product Hunt | Customizable email templates keep the connector's personal tone while the workflow stays fully automated | Client-reported |
| Delivery | Concept to a live product in 12 weeks | A state machine handling draft, sent, accepted, declined, expired, and re-sent transitions across Gmail, Outlook, and other clients | Product-recorded |
the build
What we built
IntroJoy is built around a single discipline: the connector's effort ends when they hit send. Everything that follows (confirmation, connection, tracking) is handled by the platform.
Neither party gets connected without explicitly saying yes
Each party receives an independent opt-in email carrying the connector's introduction text. Neither party sees the other's contact details until both have accepted. Declining or not responding within the expiry window closes the introduction without either party being connected without consent. The confirmation links work across Gmail, Outlook, and other clients without requiring recipients to create an account.

Connector's work ends at submission: the platform handles everything after
Connectors enter the two parties' details, draft the introduction text, and submit. The platform handles everything from that point: sending confirmation emails to each party, monitoring responses, triggering the mutual introduction when both accept, and sending reminders if a party has not responded after a set period. The connector's involvement ends at submission.

Tone stays personal, structure stays consistent every time
Connectors work from pre-built templates that carry their name, the introduction context, and the call to action. Templates are editable before sending so the tone stays personal, but the structure is consistent. The preview view shows exactly what each party will receive before the introduction is sent.

Connectors see every outcome without following up manually
Every introduction is visible from the dashboard with its current state: pending acceptance from party A or B, both accepted, declined, or expired. Connectors see the outcome of every introduction they have made without manually following up or tracking anything in a spreadsheet. Completed introductions include the timestamp each party accepted.

The lesson
Automation cannot cost you the warmth
The entire value of a warm introduction is that it carries the connector's credibility and feels personal. An automated flow that reads like a system email undermines that credibility immediately. The design challenge was making the confirmation email feel like it came from a person, using the connector's own name, their drafted introduction text, and the context they provided, while the underlying workflow was fully automated.
That is the line IntroJoy walks. The structure is rigid: consent from both sides, confirmed before any contact details are shared, with a clean exit when one party declines. The tone is human: the connector's words, their context, their name. Automate the coordination. Never automate the voice.
How it runs
- React
- The introduction dashboard shows multiple active introductions simultaneously, each at a different state. React's component model gave us the interactive, real-time status view those concurrent states required without a page reload per introduction.
- Node.js
- The backend handles email dispatch, opt-in confirmation webhook processing, state machine transitions, reminder scheduling, and expiry logic, all concurrently. Node's event-driven model managed those async workflows without thread management overhead.
- PostgreSQL
- Introductions follow a defined lifecycle with distinct states and timestamps for each transition. A relational model captured that history with the transactional integrity needed to prevent duplicate state updates when a confirmation link was clicked more than once.
- AWS
- An introduction platform where confirmation emails land in spam fails by definition. AWS SES provided high-deliverability email dispatch with SPF and DKIM configuration. Lambda ran the reminder and expiry workflows on schedule without dedicated server infrastructure to maintain.
Common questions
When a connector submits an introduction, both parties receive a separate email carrying the connector's introduction text. Each email contains a clear Accept or Decline link. Party A's response does not depend on party B's: each accepts or declines independently. Only when both parties have clicked Accept does the mutual introduction email go out, sharing contact details with each person. If either party declines or does not respond within the expiry window, the introduction closes without either party being connected without consent. Neither party needs to create an IntroJoy account to confirm.
IntroJoy sends all emails from the platform's own mail infrastructure using the connector's name and customized introduction text. The recipients experience the email in their native inbox (Gmail, Outlook, or any other client) without any plugin or extension required. The platform was originally explored as a Chrome extension but was built as a web app to ensure the full experience worked without browser-specific dependencies and was accessible on any device.
The platform sends automatic reminders to the non-responding party at configurable intervals. If the reminder window expires without a response, the introduction closes and the accepting party is notified that the introduction did not complete. The connector sees the status update in their dashboard. They can choose to re-initiate the introduction at any point, or the accepting party can contact the connector directly if they want to proceed another way. No contact details are shared until both parties have accepted.
Templates are managed by each connector within their IntroJoy account. The structure (connector name, introduction body, the two parties' names, and the opt-in call to action) is fixed, but the body text and framing are fully editable before each introduction is sent. For organizations rolling out IntroJoy across a team, shared template libraries allow a consistent introduction style to be maintained across multiple connectors without each person writing from scratch.
We built IntroJoy (double opt-in email flow, introduction state machine, connector dashboard with real-time status, customizable email templates, reminder scheduling, and expiry logic) in 12 weeks. The product launched in that first version and reached 10,000 users in six months, which validated the scope decision to ship core functionality first rather than building every possible feature before launch. A platform that also handles two-sided matching, CRM integration, or team-level analytics would take longer. Contact us to scope based on your platform's requirements.
Related work
More work like this

Elearning app development case study: a creator-led music learning platform built on Flutter, Hasura, AWS, and RevenueCat over two years
A creator-led music learning platform for Irish traditional music, built over two years across four releases. 48,100 tracked practice minutes, 100+ learners, and a subscription model built on RevenueCat rather than raw store APIs.

ULT Movies reaches 4,000 remote theaters with custom OTT app
Leading Indian movie distributor, ULT Movies, solved the challenge of delivering new releases to remote theatres with an Android app for STBs. Now, the distributor delivers smooth movie access even in areas with limited internet connectivity.

PSi: anonymous real-time voice discussions for 300+ simultaneous participants
PSi replaced slow, expensive in-person deliberation sessions with anonymous real-time voice discussion. 300+ users in simultaneous audio. Delivered in 14 weeks.