Cold Start & UX Patterns

This page documents the cold start problem in depth, lessons from prior proximity apps, and concrete UX patterns for onboarding, async delivery, network growth, and identity recovery — specific to an app with no accounts, no server, and no directory.


1. The Cold Start Problem

"Cold start" typically refers to a new user arriving on a platform with no existing network. For most social apps this means seeing an empty feed. For this app the problem is structurally deeper: zero contacts means zero functionality, not just an empty feed.

Three Distinct Cold Start Layers

Network cold start — the app has no utility until a user has at least one contact.

Compare to conventional apps:

App Value at zero contacts
Twitter / X Full read access to public content
Signal Can message yourself; import contacts by phone number
WhatsApp Imports your phone contacts on first launch
Email Can compose and send to any address immediately
This app Zero. Nothing works. No messages to read, no people to find.

This is not a bug — it is a direct consequence of physical-first trust. But it means the onboarding flow cannot afford to leave a user alone after account creation. The entire first session must orient the user toward their first contact exchange.

Discovery cold start — even with contacts, BLE sync only delivers messages when devices are physically near each other. A user in a city with no other installed base never receives anything, regardless of how many contacts they have in other cities.

This is fundamentally different from network cold start. A user could have 20 contacts on the app and still experience it as "broken" if they never physically encounter those contacts. The app can technically be working correctly while feeling completely dead.

Retention cold start — if users install and add a few contacts but rarely encounter them physically, the experience looks like a broken messenger. "I sent a message three days ago and it has never been marked delivered." This is an expectations problem, not a technical failure.

Without explicit framing, users apply the WhatsApp mental model: sent = delivered (usually within seconds), not delivered = something is wrong. The app needs to correct this model at onboarding and reinforce it throughout.

Comparison to Similar Cold Start Situations

Project Cold Start Strategy Outcome
FireChat Crisis-driven spike adoption (Hong Kong 2019: 100k downloads in 24h) High spikes, near-zero retention after each event
Briar Targeted activists and journalists who already trust each other. Cold start is an accepted limitation. Small but dedicated user base; no general consumer growth
Meshtastic Community builds physical infrastructure (LoRa nodes). Users ARE the network. Growing enthusiast community; event-driven density clusters
Nearby Share / AirDrop Ships on every device; single-use-case (file transfer); no social graph required Ubiquitous — zero network dependency for core value
Mesh games (Walking Dead events) Proximity gaming with real-world events. Users opt in for compelling experience. Short-lived but proved users accept proximity constraints for the right experience

Key insight from this comparison: The most successful proximity-constrained apps either (a) shipped pre-installed with zero friction or (b) targeted communities where members already congregate physically and already trust each other. General consumer growth is a trap.


2. Lessons from Failed and Succeeded Proximity Apps

Yik Yak — Failed

Yik Yak combined anonymous identity, proximity radius (~5 miles), and public broadcast. At its peak in 2014 it was the fifth most downloaded app in the US. It failed completely and was shut down in 2017.

What went wrong:

Lesson for this app: Never combine anonymity with public broadcast at proximity scale. The design must be private-by-default: content only goes to explicit contacts, never to "everyone nearby." The anonymous count of nearby devices (for ambient awareness) must never resolve to identifiable content.

FireChat — Succeeded Then Failed

Open Garden's FireChat used a mesh networking approach based on Apple Multipeer Connectivity. It gained significant traction in crisis contexts: Taiwan (2014), Hong Kong (2014, 2019), Iraq (2014), Catalonia (2017).

What worked:

What failed:

Lessons for this app:

  1. End-to-end encryption must be day one, not a later addition. Once a trust violation is discovered it permanently damages credibility
  2. Design for sustained daily use cases, not just emergencies. Crisis-readiness is a bonus, not a strategy
  3. A crisis-driven spike is not product-market fit

Bridgefy — Partially Succeeded

Bridgefy gained 12.5 million users between 2019 and 2020, driven by protests in Hong Kong, Chile, Iran, and Belarus, plus COVID-era use cases.

What worked:

What failed:

Lessons for this app:

  1. Security is not a feature — it is the product. One published audit failure destroys the entire value proposition for the target audience (people who need private communication)
  2. Proactive independent audits before launch are table stakes. "We haven't been audited yet" is not acceptable for a privacy-first app
  3. The social graph is as sensitive as the message content. Protecting metadata (who communicates with whom) must be explicit in the architecture

Briar — Niche Success

Briar is a free, open-source messenger designed for activists, journalists, and people under authoritarian surveillance. It supports Bluetooth, WiFi, and Tor for transport.

What works:

Limitations:

Lessons for this app:

  1. A clear, specific target audience sidesteps the consumer cold start problem entirely
  2. The "people who already know and trust each other" framing makes the physical-first trust model an asset, not a limitation
  3. UX polish is a competitive advantage in the activist/journalist niche, where users often use Briar because they have no other option

Meshtastic — Growing Community

Meshtastic is an open-source LoRa mesh networking project. Users buy LoRa radio hardware, flash Meshtastic firmware, and form a physical network infrastructure.

What works:

Relevance to this app:

Lesson: Event-driven adoption creates repeatable, sustainable density clusters. Design for communities that already congregate, not for individuals who happen to be near each other.

Nearby Share and AirDrop — Infrastructure Cold Start Solved by Default Installation

Both Apple AirDrop and Google Nearby Share solved the cold start problem by eliminating it: the feature ships on every eligible device and has a single, clear, non-social use case (file transfer).

Why this matters:

Lesson: If possible, ensure the app delivers value for a single-person use case before the network grows. The equivalent here is: the app should be useful as a local, encrypted notes tool or offline journal even with zero contacts — something that prevents uninstall during the waiting period.


3. Onboarding Without Accounts

First Launch — What Happens

The onboarding flow must accomplish five things without a sign-up form, phone number, email address, or username:

  1. Generate a keypair silently
  2. Help the user understand that this device IS their identity
  3. Secure the keypair with a backup mechanism
  4. Show the user what to do next (find someone to add)
  5. Set correct expectations about message delivery
FIRST LAUNCH FLOW

 ┌─────────────────────────────────────────────────────────┐
 │  "Welcome"                                              │
 │                                                         │
 │  No account. No email. No password.                     │
 │  Your identity is a cryptographic keypair,              │
 │  generated right now on this device.                    │
 │                                                         │
 │  [Generate my identity →]                               │
 └─────────────────────────────────────────────────────────┘
           │
           ▼
 ┌─────────────────────────────────────────────────────────┐
 │  "Back up your identity"                                │
 │                                                         │
 │  If you lose this phone without a backup,               │
 │  your identity and contacts cannot be recovered.        │
 │                                                         │
 │  [Set up backup →]  [Remind me later — skip for now]    │
 └─────────────────────────────────────────────────────────┘
           │
           ▼ (if backup chosen)
 ┌─────────────────────────────────────────────────────────┐
 │  "Your recovery phrase"                                 │
 │  (12 words, shown one at a time on tap)                 │
 │  [Confirm phrase — type words 4, 7, 11]                 │
 └─────────────────────────────────────────────────────────┘
           │
           ▼
 ┌─────────────────────────────────────────────────────────┐
 │  "Ready."                                               │
 │                                                         │
 │  Here is your code. Show it to someone                  │
 │  to add them as a contact.                              │
 │                                                         │
 │  [QR CODE — large, centered]                            │
 │                                                         │
 │  Or scan someone else's code to add them.               │
 │  [Scan a code]                                          │
 └─────────────────────────────────────────────────────────┘

The QR code on the final screen is functional immediately — no further setup required. Showing it on the final onboarding screen collapses the gap between "finished setup" and "first useful action."

The Backup Problem — Making It Feel Like Setup, Not a Warning

Crypto wallet teams have accumulated years of experience with this exact problem. The learnings:

What does not work:

What works (observed from MetaMask, Rainbow, Argent, Ledger):

Approach What it does Why it works
Progressive commitment Allow limited use before requiring backup; show a persistent "You're not backed up" banner Lets users see value first; banner is less alarming than a gate
Gamified confirmation After showing 12 words, ask the user to confirm 3 random words by tapping Proves they wrote it down; feels like a quiz, not a lecture
Narrative framing "Your recovery phrase is like a spare key to your home" instead of "CRYPTOGRAPHIC SEED" Human language reduces cognitive load
Show-one-at-a-time reveal Words are shown one at a time, user taps to advance Slows down the reveal; prevents screenshot-only backup
Trusted contact sharding "Share recovery pieces with 3 trusted friends — you only need 2 to recover" Social recovery feels more natural than writing down words

Recommended pattern for this app:

  1. Show the backup option at end of onboarding, after keypair generation but before the first contact screen
  2. Frame it as: "Set up your recovery — takes 2 minutes"
  3. Show 12 words, one tap at a time, with a "hold to reveal" interaction
  4. Confirm with 3 random words before proceeding
  5. If the user skips: show a persistent but non-blocking banner: "Identity not backed up — tap to protect your contacts and messages"
  6. Offer Shamir secret sharing as an alternative for users who don't want to manage a phrase: "Share a recovery key with 3 people you trust. Any 2 can help you recover."

The Empty State After Onboarding

After setup completes, the user has: zero contacts, zero messages, a working cryptographic identity, and no idea what to do.

Empty state options, from worst to best:

Approach Problem
Blank screen with nav User does not know what to do; churn risk is high
"Invite a friend" button Requires the user to convince someone else to install first
Tutorial carousel Users skip tutorials; information not retained
Contextual QR code + action prompt Gives the user something to DO right now

Recommended empty state UI:

 ┌─────────────────────────────────────────────────────────┐
 │                                                         │
 │            Ready to connect.                            │
 │                                                         │
 │   Find someone else with the app and show              │
 │   them this code to add each other.                     │
 │                                                         │
 │         ┌──────────────────────────┐                   │
 │         │                          │                   │
 │         │   [QR CODE — large]      │                   │
 │         │                          │                   │
 │         └──────────────────────────┘                   │
 │                                                         │
 │   Or scan their code:  [Scan]                           │
 │                                                         │
 │   ─────────────────────────────────────────────        │
 │   When you add your first contact, you'll see           │
 │   their messages the next time you're nearby.           │
 │                                                         │
 └─────────────────────────────────────────────────────────┘

Additional empty state patterns to consider:

First Contact Establishment UX — The NFC Tap

The contact exchange moment is the most important interaction in the entire app. It needs to feel instant, magical, and clear — not technical.

The NFC tap flow:

INITIATOR (Alice)                    RECIPIENT (Bob)

  [Shows QR / holds phone near]      [Holds phone near / scans QR]
         │                                    │
         └──── NFC field detected ────────────┘

   "Tap detected"                    "Tap detected"
   (haptic + visual pulse)           (haptic + visual pulse)
         │                                    │
         └──── Key exchange (< 2 sec) ────────┘

   "Connected to                     "Connected to
    someone new!"                     someone new!"

   "What do you want to              "What do you want to
    call them?"                       call them?"
    [text input]                      [text input]
    [Skip — name later]               [Skip — name later]
         │                                    │
         └──────── Contact saved ─────────────┘

   "Done. You'll get their           "Done. You'll get their
    messages when you're              messages when you're
    nearby."                          nearby."

Key UX decisions in this flow:

  1. The haptic feedback on NFC detection is critical — it confirms the physical gesture without requiring the user to look at the screen
  2. "Connected to someone new!" — not "Key exchange complete" or "Contact added" — the language is social, not technical
  3. Naming is optional and skippable. Before the user assigns a name, the contact appears as "New contact (met [date])" or, if the other person shared a display name, that name is used
  4. The post-exchange confirmation screen stays visible for several seconds and includes the next-step explanation: messages deliver when nearby

What data is exchanged at contact add time (minimum viable):

Field Required Notes
Ed25519 public key Yes Identity key
X25519 DH public key Yes For key agreement
ML-KEM public key Yes Post-quantum key exchange
Display name (optional) No Chosen by each user for themselves; other party sees it or assigns their own
Timestamp Yes For "met on [date]" display

Nothing else. No phone number, no email, no location, no profile picture at this stage.

Before a name is assigned, what is the contact called?

Options:

The key principle: never show a cryptographic public key hash as the name. That is a developer interface, not a social one.


4. Explaining Async / Delayed Delivery

This is the hardest UX challenge in the entire app. The expected mental model (WhatsApp: sent = delivered in seconds) is wrong. The correct mental model is much older.

The Mental Model Gap

User's assumption The actual model
"Sent" means the recipient got it immediately "Sent" means it is queued on your device
Undelivered = broken Undelivered = recipient not yet nearby
3 days with no read receipt = ignored 3 days undelivered = haven't been near each other
Internet required for messaging BLE range (~30m) is the "internet"

The correct analogies to plant in the user's head:

Message State Design

Every message needs clear state indicators that normalize the queue model:

MESSAGE STATES

  ✏  Composed        — typed but not yet sent from device (draft)
  ◷  Queued          — sealed and waiting on your device for next sync
  ✓  Synced          — delivered to contact's device at last encounter
  ✓✓ Read            — contact has opened the message (optional, privacy trade-off)

The key design decision: never show an error state for a message that is simply waiting. "Not delivered" implies failure. "Queued — will deliver when nearby" implies intentional design.

UI language for message states:

State Wrong language Right language
Waiting to sync "Not delivered" "Queued — waiting for next sync"
Successfully synced "Delivered" "Synced" or "Delivered"
Contact not seen in 7+ days "Message stuck" "Last seen 7 days ago — will sync on next encounter"

Contact Last-Seen Indicator

Each contact in the list should show their last sync time and, optionally, a coarse location:

 Alice                         Last sync: 2 days ago, near Soho
 Bob                           Last sync: 4 hours ago
 Carol                         Never synced
 Dan                           Last sync: just now  ●  (in range)

Privacy notes on coarse location:

In-Range Notification

When a contact comes into BLE range and a sync occurs, the user should know:

 ─────────────────────────────────────────────
 Synced with Alice  —  3 messages delivered
 ─────────────────────────────────────────────

This notification does double duty:

  1. Confirms the async model is working ("see, it delivered when she was nearby")
  2. Creates a moment of delight — an unexpected message arrival is more satisfying than an expected instant delivery

For users with no contacts currently in range, a persistent status element (not a notification — just ambient UI) can show: "Listening for contacts... (0 in range)". This makes the app feel active rather than dead.

Setting Expectations at First Use

A dedicated onboarding screen — not a tooltip, a full screen — should explain the model before a user sends their first message:

 ┌─────────────────────────────────────────────────────────┐
 │                                                         │
 │  Messages deliver when you're nearby.                   │
 │                                                         │
 │  This app does not use the internet by default.         │
 │  Messages are delivered via Bluetooth when your         │
 │  phones are within range of each other.                 │
 │                                                         │
 │  This means:                                            │
 │                                                         │
 │  ✓  Your messages never touch a server                  │
 │  ✓  No one can intercept them in transit                │
 │  ✓  They deliver the next time you're near              │
 │                                                         │
 │  Think of it like leaving a sealed letter at            │
 │  someone's door — it will be there when they            │
 │  get home.                                              │
 │                                                         │
 │  [Got it →]                                             │
 │                                                         │
 └─────────────────────────────────────────────────────────┘

Frame this as a feature ("never touch a server"), not a limitation. The privacy-conscious user who is the target audience will respond positively to this framing.


5. Growing Your Network

Without a directory, search, or "people you may know" algorithm, network growth must be entirely physical and community-driven.

Natural Growth Vectors

1. In-person events and regular gatherings

The highest-density use cases are places where the same people repeatedly meet:

Context Why it works
Coworking spaces High daily density; members see each other repeatedly
University campuses High density, long dwell time, existing social clusters
Activist and mutual aid groups Already need private communication; motivated users
Maker spaces and hackathons Technical audience; early adopters; event-driven gatherings
Hiking / outdoor clubs Regular group activities; offline context is natural
Local community groups Geographic density; recurring meetings

These contexts share a property: the physical gathering already exists. The app does not need to create density — it needs to be useful in density that already exists.

2. Contact-of-a-contact introductions

Alice can introduce Bob to Carol without them needing a server:

INTRODUCTION FLOW

1. Alice composes a signed introduction message:
   "I'd like to introduce you to Carol [Carol's public key]"

2. Alice sends this to Bob (via BLE sync, next encounter)

3. Bob receives Alice's vouching for Carol

4. When Bob and Carol meet in person, they complete the
   exchange (NFC tap / QR scan)

5. Bob's device confirms: "Carol introduced by Alice"
   — this is a trust signal, not automatic contact add

The critical design constraint: the introduction lowers friction and creates context ("I know Carol through Alice"), but the in-person exchange is still required. The introduction cannot substitute for physical meeting. This preserves the physical-first trust guarantee.

3. QR codes on physical objects

Static QR codes can represent identities or groups:

These are one-way introductions: the QR owner does not automatically receive a contact. The exchange must still be mutually completed, which can happen at the event.

4. Event-specific group codes

For a conference, meetup, or protest:

ORGANIZER CREATES EVENT GROUP

 1. Organizer generates a time-limited group QR code
 2. Code is printed, projected, or shared verbally as short numeric PIN
 3. Attendees scan code or enter PIN
 4. All scanning devices join a temporary proximity group
 5. Group exists for the duration of the event
 6. After the event, group members can convert to direct contacts by tapping phones

The "physical meeting" is the event itself.

This is the one sanctioned exception to strict one-on-one contact establishment. The event QR is a bounded trust context: everyone present at this location, at this time, agreed to participate.

The Density Problem and Its Mitigation

A proximity discovery feature ("see who's nearby") only works when local user density is high enough. This creates a trap: new users see no one nearby and uninstall, which prevents density from building.

Mitigation strategy: the app must be valuable as a private messenger for existing contacts before any proximity discovery feature matters.

This means:

Do not show a "people nearby" count when it will be zero. An empty list reinforces the "nobody uses this" perception. Instead: show a subtle ambient indicator ("listening for contacts") that does not quantify. When users start appearing in range, show them contextually.

Preventing Uninstall During the Growth Phase

Risk moment Mitigation
Just installed, zero contacts QR code visible immediately; action prompt; no empty dead screen
Has contacts but hasn't synced in 3+ days "Pending messages" indicator; explain the model; no false error state
Synced but no response from contact No "read receipt" anxiety; framing around privacy value
Never encounters contacts physically Offer online (Tor) opt-in as bridge; normalize async; suggest use cases

6. Backup and Recovery UX

Recovery Scenarios

Scenario Path Outcome
Phone lost, had mnemonic backup New install → "Restore identity" → enter 12 words Full identity restored; message history syncs over time on next contact encounters
Phone lost, had Shamir shares (3-of-3, threshold 2) New install → "Restore identity" → "Use trusted contacts" → meet 2 of 3 in person Full identity restored; requires physical meetings to collect shares
Phone lost, no backup New install → "Start fresh" Complete loss of identity; contacts still have message history; re-add contacts in person
Phone destroyed, backup exists Same as scenario 1 or 2 above Same recovery as above
Phone seized, backup secured offline Same as scenario 1 or 2 above Key not accessible on seized device if encrypted; backup remains secure

The Mnemonic Restore Flow

NEW INSTALL — RESTORE PATH

  [Install app]

  ┌─────────────────────────────────────────────────────────┐
  │  "Do you have an existing identity?"                    │
  │                                                         │
  │  [Restore with recovery phrase]                         │
  │  [Use trusted contact recovery]                         │
  │  [Start fresh — new identity]                           │
  └─────────────────────────────────────────────────────────┘

         ↓ (restore with phrase)

  Enter your 12 recovery words
  [word 1] [word 2] ... [word 12]

  Identity reconstructed.

  ┌─────────────────────────────────────────────────────────┐
  │  Identity restored.                                     │
  │                                                         │
  │  Your key has been recovered. Your contacts             │
  │  will recognize you when you're near them.             │
  │                                                         │
  │  Your message history will sync back the next          │
  │  time you encounter each contact.                       │
  │                                                         │
  │  [Continue →]                                           │
  └─────────────────────────────────────────────────────────┘

Important UX decision: do not promise to restore message history immediately. It cannot be restored from the key alone — the messages live on contacts' devices. The user needs to know: "Your identity is restored. Your history comes back gradually as you meet your contacts." This is accurate and prevents a support complaint ("I restored but all my messages are gone").

Trusted Contact Recovery (Shamir Shards)

For users who prefer not to manage a 12-word phrase, Shamir Secret Sharing lets them distribute the key across trusted contacts:

SETUP (done once, during backup configuration)

 "Choose 3 trusted contacts to hold your recovery key.
  You will need to meet 2 of them in person to recover
  your identity."

 [Select Alice]  [Select Bob]  [Select Carol]

 → A signed, encrypted shard is generated for each
 → Shards are sent to contacts via next BLE sync
 → Each contact's device stores the shard, encrypted to their key

RECOVERY (on new device)

 "Recover with trusted contacts"
 → Meet Alice in person → Alice's device transfers her shard
 → Meet Bob in person → Bob's device transfers his shard
 → 2 shards = full key reconstructed

This approach has a UX advantage: it turns key recovery into a social, physical process. It reinforces the app's values (physical trust, no servers) rather than contradicting them.

Contact Notification of Device Change

When a user restores their identity on a new device, their contacts should know:

No server-pushed notification is possible. The "device change" announcement propagates opportunistically through the BLE mesh. This is slower than a push notification but preserves the offline-first architecture.

The Start-Fresh Path — Dignity for Users With No Backup

A user who loses their phone and has no backup loses everything. The app must make this path dignified:

 ┌─────────────────────────────────────────────────────────┐
 │  Starting fresh.                                        │
 │                                                         │
 │  Your previous identity cannot be recovered             │
 │  without a backup.                                      │
 │                                                         │
 │  A new identity has been created for you.               │
 │                                                         │
 │  Your contacts still have your past messages.           │
 │  When you meet them again, you can add each              │
 │  other as new contacts.                                 │
 │                                                         │
 │  This time, back up your identity immediately.          │
 │                                                         │
 │  [Set up backup →]  [Skip — do this later]              │
 └─────────────────────────────────────────────────────────┘

Do not: show a red error screen, use the word "lost", or make the user feel punished. They will use the app again, and they can rebuild their network. This is genuinely true — the contacts still have the history, and the relationships are real.


7. Event-Driven Adoption Strategy

Based on the lessons above, general consumer growth is not a viable strategy. The only proven path to sustainable density is community cluster adoption.

Target Community Types

Community type Why they fit Adoption trigger
Activist and protest organizers Need private, surveillence-resistant comms; already trust each other Explain the security architecture; get one technical champion
University student groups High density; repeated physical meetings; early adopters On-campus events; student tech orgs
Disaster preparedness / CERT groups Need offline comms; already practice physical meetings Works without internet — perfect pitch
Maker spaces and hackerspaces Technical audience; community infrastructure mindset Tool demos at member meetings
Mutual aid networks Existing trusted relationships; privacy-conscious Community organizer outreach
Local cycling / outdoor clubs Regular group rides and hikes; offline-first is a natural fit Event QR codes on ride sheets

Event Feature Design

Events are the highest-density moments for these communities. Features to build around events:

Pre-event QR code:

At-event ambient presence:

Post-event follow-up:

Organizer controls:

Community Infrastructure Investment

Meshtastic's lesson: if you get a community to invest in building infrastructure together, they become advocates and maintainers of that infrastructure.

For this app, the equivalent is not hardware — it is the social graph itself. When a community's trusted members all add each other, the BLE mesh among those members becomes community-owned communication infrastructure. Encourage this with:


8. UX Principles Summary

These principles are derived from the analysis above. They are intended to guide design and product decisions throughout development.

Core Principles

1. Useful on day one for existing relationships

The app must deliver value as a private messenger for people you already know, before any proximity discovery or network density effects apply. A user with 3 existing contacts and the app on all 3 phones should have a better messaging experience than Signal for privacy-sensitive conversations — even if they only sync when physically near.

2. Make backup feel like setup, not a warning

Key backup must happen at onboarding, framed as a completion step ("set up your recovery"), not as a security warning ("WRITE THESE WORDS DOWN"). Use progressive disclosure, gamified confirmation, and human-language framing. Offer Shamir social recovery as an alternative for users who find mnemonics alienating.

3. Normalize async delivery — never show a false error

"Not delivered" is never the correct message for a queued message. The message is not lost; it is waiting. Pending, queued, and waiting states must be clearly distinguished from failure states. Delivery on encounter should feel like a pleasant notification, not a resolution of an error.

4. Physical gestures should feel like superpowers

The NFC tap moment — the signature interaction of the entire app — must be designed to feel instant, delightful, and magical. Haptic feedback on detection. Smooth animation on key exchange. "Connected to someone new!" Social language throughout. If the tap feels like configuring a device, the product has failed.

5. Never show a count of nearby strangers

No "47 people nearby" view. No list of non-contact identities. A count of anonymous nearby users is acceptable (for ambient social proof at events); resolving that count to identities is a Yik Yak pattern. The only people with names in the UI are contacts who have been physically introduced.

6. Target communities, not consumers

Cold start cannot be solved with consumer viral growth for this type of app. It can be solved by targeting communities where members already trust each other, already meet regularly, and already have a communication need that existing tools handle poorly (due to surveillance risk or infrastructure dependency). Events, not algorithms, create density.

7. Crisis-ready, not crisis-dependent

The app should work excellently in crisis contexts (protests, natural disasters, network outages). It should not require a crisis to deliver value. Design the daily use case first: private messaging for people you trust, with no server involvement. The crisis utility follows from that design; it does not define it.

Anti-Patterns to Avoid

Anti-pattern Why it is harmful Better alternative
"People nearby" stranger list Harassment vector; Yik Yak lesson Anonymous count only; contacts only in list view
Push notification for undelivered messages Creates false urgency; breaks the mental model Show queued state; notify on sync
"Failed to send" for queued messages Implies error when system is working correctly "Queued — will sync when nearby"
Import phone contacts on first launch Leaks contact metadata; breaks anonymity model Physical exchange only
Public profile / username directory Enables surveillance; destroys anonymity Keypair identity only; no namespace
Mandatory account before backup Skews to server dependency; contradicts design Keypair is the account; backup is local
"Find friends" features Requires a directory; breaks the model entirely Event-based group QR codes only
Delivery receipts by default Metadata leakage; reveals contact graph timing Opt-in read receipts only

Decision Framework for New Features

When evaluating a proposed feature, apply these tests:

  1. Does it require a server to work? If yes, it is opt-in only, never default.
  2. Does it reveal the social graph to any third party? If yes, it cannot be built.
  3. Does it require PII (name, phone, email)? If yes, make it entirely optional and local.
  4. Does it create a "people you may know" signal? If yes, do not build it.
  5. Does it improve the experience for a user with zero contacts? If yes, prioritize it.
  6. Does it make the first NFC tap more delightful? If yes, prioritize it.
  7. Does it explain the async model more clearly? If yes, prioritize it.