FIELD NOTES / CONSUMER SOCIAL

The plan lives in six places.
None of them agree.

Crew lets people discover nearby activities, invite a group, manage who is actually coming, coordinate in event-specific chat and split shared costs — inside one structured event rather than across posts, group chats, spreadsheets and a separate payment app.

CONSUMER SOCIAL CASE STUDY

Crew

One event object.
Everything resolves against it.

Built and delivered
Crew / Nearby discoveryACTUAL PRODUCT INTERFACE
Crew discovery map showing nearby activities available to join
THE COORDINATION PROBLEMComments are not a headcount.

Who is definitely going? Who is undecided? How many spaces remain? Who still needs to pay? A thread of reactions cannot answer any of those reliably.

Follow an event ↗
DiscoverCreateInviteRSVPSettle
DOMAIN

Social / consumer technology

WHAT WE BUILT

Event coordination and discovery platform

OUR ROLE

Product engineering to real-time backend

01 / THE COORDINATION GAP

Social platforms distribute content.
They do not organise people.

Organising a real-world activity today means posting on social media, messaging several group chats, tracking attendance by hand, sending the location separately, chasing reminders, absorbing last-minute changes, and using another tool entirely to collect money.

Traditional social platforms are optimised for content distribution, not structured participation. Group chats only reach people the organiser already knows; general feeds offer no structured location- or activity-based discovery.

Crew was designed for the space between those models: small-to-medium real-world activities that need both discovery and coordination.

01

Coordination is spread across tools

Attendance, logistics, communication and payments each live somewhere different. Nothing reconciles them, so the organiser becomes the reconciliation layer.

02

Participation is ambiguous

Comments and reactions do not answer who is definitely going, who is undecided, how many spaces remain, who cancelled, or who still owes money.

03

Discovery stops at people you know

A group chat reaches an existing circle. A public feed reaches everyone and organises nothing. Neither surfaces an activity happening nearby this weekend.

02 / INSIDE THE PRODUCT

Find it. Join it.
Settle up afterwards.

Four views of the delivered application.
Each shows another stage of an event's life, from discovery through to the money.

Crew map view showing nearby activities filtered by proximity and type

Activity discovery, by where you actually are.

Nearby activities surfaced through geographic proximity and activity filtering, with the map layer handled by Mapbox while the backend decides visibility, eligibility and capacity.

Crew map view showing nearby activities filtered by proximity and type
IDEA TO SETTLED EVENT

CreateDiscoverInviteRSVPCoordinateContributeAttend

03 / ONE OBJECT, NOT SIX INTEGRATIONS

The event is the
primary system object.

Discovery, invitations, attendance, messaging, payments and notifications all connect back to the same event identity. That single decision is what stops the product becoming another collection of loosely-joined features.

It also shaped the backend: event, RSVP, membership, payment and chat are highly related domains, so they stay in one modular service rather than being split into services that would then need distributed transactions to agree with each other.

Look under the hood ↘
01

An invitation is not a membership

Invitations are held as separate records, so being invited does not silently make someone a participant before they accept.

INVITATION ACCEPTED

Becomes a participant

The person enters the attendance model, counts against capacity, gains chat access and inherits any payment obligation the event carries.

INVITATION PENDING

Stays outside the count

Capacity, notifications and chat treat them as not yet attending, so the organiser's headcount reflects commitments rather than hopes.

02

Chat access follows event membership

Authorization is tied to the participant record rather than trusting the client to join the right room, and messages persist before broadcast so real-time delivery is not the only copy.

03

Payment state is confirmed by the server

Contributions reconcile through signed Stripe webhooks. A client-side success screen cannot safely determine whether money actually settled.

04 / THE TECHNOLOGY & THE REASON

Related domains stay together.
The map layer does not.

The stack follows the same principle as the product: things that must agree with each other live in one place, and the parts that genuinely are someone else's specialism — mapping, payments, push — are integrated rather than rebuilt.

MOBILE CLIENT

React Native

One cross-platform application for iOS and Android, with platform-specific integration for push, permissions, secure storage, deep links and lifecycle handling.

Why cross-platform here?

Core behaviour stays aligned between the two platforms, while the genuinely native concerns are handled natively rather than through a weakening abstraction.

APPLICATION LAYER

Node.js + Express

A modular, domain-oriented API covering events, RSVP, membership, payments and chat as related modules inside one service.

Why not microservices?

These domains constantly reference each other. Splitting them early would buy distributed transactions, schema duplication and tracing overhead without a product benefit.

TRANSACTIONAL TRUTH

PostgreSQL

Holds the state that has to be correct under contention — RSVP capacity, invitation acceptance, participant membership and payment status.

Why relational?

Capacity and acceptance are transactional questions. Two people taking the last place is a correctness problem, not an eventual-consistency one.

REAL-TIME LAYER

Socket.io

Event-scoped conversations delivered in real time, with messages persisted before broadcast and room access authorized against event membership.

Why persist first?

Real-time delivery should not be the only copy of a conversation. A dropped socket must not mean a lost message.

LOCATION LAYER

Mapbox

The mapping and geographic interaction layer behind nearby-activity discovery.

Why keep rules on the server?

Mapbox draws the map; it does not decide who may see an event. Visibility, eligibility and discovery rules stay in the backend where they can be enforced.

SHARED COSTS

Stripe

Event-level contributions for shared expenses, created by the backend and reconciled through signed webhooks.

Why webhook reconciliation?

The only trustworthy signal that a contribution settled comes from Stripe itself, not from a screen the client happened to reach.

The confirmed stack is React Native, Node.js, Express, PostgreSQL, Socket.io, Mapbox, Stripe, Firebase Cloud Messaging and APNs. The source additionally proposes an AWS production topology; those services are a recommended architecture rather than confirmed implementation, and are not claimed here.

Explore the documented platform stack

Mobile
React Native · iOS and Android · native push and storage
Application
Node.js · Express · modular domain boundaries
Data
PostgreSQL · transactional RSVP and membership state
Real-time
Socket.io · event-scoped rooms · persisted messages
Integrations
Mapbox · Stripe · Firebase Cloud Messaging · APNs

Technology names identify the documented implementation, not partnerships or endorsements.

A CONVERSATION ABOUT YOUR COORDINATION PROBLEM

What is your product
actually organised around?

Bring one workflow where people, plans and money currently live in different tools. In 30 minutes, we will look at what your primary object should be, and what stops agreeing once it is not.

30 minutes · Your users, your coordination workflow

CONTACT PREVIEW

Contact destination

No message has been sent. The destination will be connected before outreach.