CCasey White
← All work
Cocoon logoPre-launch

Cocoon

A quiet channel through the noise.

Bluetooth links two phones directly, no internet, no cell signal, so two people can talk through their own noise-cancelling earbuds over the loudest car, kitchen, or crowd.

Category
Offline voice app
Timeline
16 hours · 24 commits
Focus
Family & everyday
Coming soon: iOS & Android
Cocoon preview
01

Why I built it

I kept thinking about the two-parents-in-a-loud-car problem: everyone wears noise-cancelling earbuds now, and none of them can talk to the person sitting right next to them without shouting over the kids. There was no app for one phone talking straight to another with no internet involved, so I built one. Cocoon links two phones over Bluetooth and carries a real conversation through the earbuds people already own. No account, no server, nothing for either phone to send anywhere. Just two people, and the quiet in between.

02

What it does for people

  • A direct phone-to-phone link over Bluetooth, so two people can talk with no internet, no Wi-Fi router, and no cell signal anywhere in range
  • Full-duplex conversation through the earbuds you already own, real back-and-forth talking, not a push-to-talk walkie-talkie
  • A voice gate that transmits nothing between sentences, so the other side hears only your voice and none of the room around you
  • Short-code pairing that gets two phones talking in under a minute, with a matching code on both screens to confirm you found the right person
  • A built-in Sound Check screen that lets you hear your own voice looped back through your earbuds before you ever start a real call
03

Under the hood

  • BLE L2CAP connection-oriented channels carrying the actual voice stream, since no OS API on either platform streams call audio from one phone to another
  • Each phone's single Bluetooth radio has to run the earbud link and the phone-to-phone link at once, which made bandwidth and scheduling contention the central engineering constraint, not an afterthought
  • RNNoise-class ML voice isolation running in the Android capture path ahead of the Opus encoder, because the platform's built-in noise suppressor does nothing against yelling kids, only steady hums
  • A peer-to-peer Wi-Fi Aware upgrade negotiated over the BLE control channel, freeing the Bluetooth radio entirely and cutting latency when both phones support it, with a silent fallback back to L2CAP
  • Custom native modules doing the real work, Swift and CoreBluetooth on iOS, Kotlin and Oboe on Android, under a thin Expo Router shell that never touches the audio or transport code
04

The cool bits

  • The first real test happened in a moving car, and it failed on radio congestion. The Sound Check screen, originally a throwaway diagnostic, is what found the problem and stayed in the shipped app as the only support tool a zero-server app can have
  • There is genuinely nothing to leak. Nothing gets logged, tracked, or sent off either phone. It could not listen even if it wanted to
  • The two brand colors carry meaning instead of just decorating the screen: sage is your own side of the call, and violet only shows up once your partner is actually there
  • The session layer already supports a host plus three guests, though the app keeps the interface honestly two-person until Wi-Fi Aware earns the extra bandwidth
05

How long it took

About sixteen straight hours, first commit to a build ready for Play Store testing.

16 hours · 24 commits

06

What I worked through

The whole app hinges on one physical constraint: each phone has a single Bluetooth radio, and it has to serve the user's own earbuds and the phone-to-phone link at the same time. That tension sits behind every latency and bandwidth decision in the codebase. The first real test, a car with both of us wearing earbuds, failed on exactly that: radio congestion pushed round-trip time from 11 seconds out to 33 under dual-link contention. Fixing it took a voice gate that stops transmitting between sentences, frame bundling, a drop to 16kbps, and eventually ML-based voice isolation so a quiet cabin didn't need a strong signal to sound clean. Getting the echo cancellation right took just as much iteration, since a car seat puts two people close enough for a guest's own voice to bleed back into their host's ear.

07

The full stack

Expo SDK 57 (bare workflow, expo-router)React Native 0.86React 19TypeScriptZustandSwift (CoreBluetooth, AVAudioEngine)Kotlin (BLE, L2CAP CoC, Oboe/AudioRecord)Opus codec (20ms frames, ADPCM fallback)RNNoise (ML voice isolation)Wi-Fi Aware (peer-to-peer upgrade path)react-native-reanimated 4expo-hapticsGitHub Actions CI