Introduction
A free, open-source, screen-free phone. Real mechanical keys, a handset, and nothing else: no browser, no feeds, no strangers.
It is a lot more than one phone. Everything runs on connections: you sign in on a public hub you trust, or federate your own servers and services, and you choose the level of safety and security you want at every step, including how available and how visible you are to each person. The same board and software make a kid’s first phone, a desk phone for grown-ups, a shared Lounge phone, a small office phone system, or (with the labs firmware) a house intercom, a doorbell and an elder’s daily check-in.
- Kids’ phone — calls only the contacts a guardian approves, respects quiet hours (callers get voicemail with a transcript instead of waking anyone up), and its guardian sees when it was last online. Kids’ phones on the market are closed boxes with a fixed feature list; this one is open, so a child can learn how it works and tinker with it as they grow, while the phone’s rules stay with their guardians until they decide otherwise. When it starts running firmware that isn’t an official update, its guardians hear about it straight away, and with Ask me first it waits for their OK.
- Voicemail everywhere — any call that isn’t answered (no answer, declined, busy, quiet hours, unavailable) goes to a greeting — the standard one, your recorded name, or your own — and the message lands in the callee’s inbox, across servers too.
- Lounge phone — a shared phone anyone in the space takes over as themselves by scanning its code and pressing the key it flashes; it forgets them the moment they’re done. People from other servers can use it too, if the space allows guests.
- Grown-ups use the companion app on their own phone or computer, or any old device as a
phone (
/device/, add it to the home screen). You choose who can reach you, whether you’re taking calls right now, and whether your connections see that you’re around. - Not just a phone — the labs firmware (firmware/labs/, 0.0.0) turns the board into a house intercom, a doorbell or front desk, a dinner’s-ready chime, a daily check-in for an elder, a Home Assistant panel, a dial-a-story line or a USB macro pad. It’s the build on the v0.1 dev boards for now (lightly tested; most of its extras so far on a computer). Its features come to the phone firmware later, where they make sense.
Run it on your own Cloudflare account or self-host it with Docker; to just try it, use the
free public hub at hub.openloungephone.app. Your keys and your
server are yours: nothing depends on this project (security model). Servers connect to each other, so everyone can reach everyone: you
knock on someone’s address (name@server), and once they accept you can call. Nobody —
including this project — sits in the middle of your calls, and there is no bridge to the phone
network, ever.
Status
Section titled “Status”The software works end to end today. The hardware has its first early dev board prototype: hardware v0.1 (rev A), ordered from JLCPCB on 2026-09-30. Its files are in that release. Board v0.3 is coming soon as a fully assembled board or a bare PCB; join the interest list.
| Phase | What | State |
|---|---|---|
| M0–M4 | Protocol and core logic; self-hosted server, browser phone, companion app; Cloudflare backend; invites, passkeys, voicemail with transcripts | done |
| Lounge | QR takeover with a key-press proof, ephemeral sessions, “open to chat” | done (software) |
| Security (software) | Four-word device fingerprint (phone MENU → About, pairing, the phone’s page); phone page with last seen, software version and remove-and-wipe; retention defaults and transcription on/off per space; an audit trail in every space (who changed what, never what was said; read only by those who run the space) | done (software) |
| Recording (C2) | Opt-in per space (never with kids’ phones), always announced to every party (spoken prompt, the phone’s status light and REC on its display, a mark in the apps, other servers too), made by the recording side’s own client and uploaded, in the timeline and call log, transcribed only where the space transcribes, expiring with history; other servers may refuse recorded calls |
done (software) |
| Device lifecycle | Modes at claim (kids, personal desk phone, Lounge); per-space Lounge session length (idle, end of day, until logout); optional house-line keys and “who’s here” on idle Lounge phones (off by default; public lines only for someone signed in); a space’s name and time zone can be changed later (Settings), and the phones follow at once; remove = the phone wipes itself | done (server, apps, browser phone); firmware: remove = wipe done, modes and factory reset later |
| P1 / P1b | Accounts and handles (name@server), several households per account, open sign-up; spaces (home, team, organization); handles reserved 90 days; recovery codes, session list and sign out everywhere, space owners and leaving (0.5.0) |
done |
| P2 | Connections (“buddies”): knock, accept, decline, block — on one server and across servers (signed server-to-server requests) | done |
| P3 | Calls across servers, voicemail, opt-in presence, Lounge guests from other servers | done |
| P4 | The public hub: free, donation-funded, fair-use allowance, Turnstile, operator view, export and account deletion | live at hub.openloungephone.app (2026-09-29) |
| Voicemail everywhere | Unanswered calls go to voicemail for every caller and callee (people, kids’ phones, Lounge guests, other servers); greetings (standard, recorded name, custom); ring time; recording the greeting on the phone | done (software) |
| P2b | Buddy timeline: per-connection history of calls and voicemails (with transcripts), expiring per connection or by your default (30 days / 1 year / forever); no text chat | done (software) |
| M5 | One-command CLI, npx openloungephone: deploy cloudflare (prompts, preflight, summary; keys never echoed), selfhost init (compose.yaml + .env with random secrets, optional coturn/LiveKit), status <url>, doctor |
done; the desktop (Tauri) app was dropped — the installable web apps cover it |
| P3.5 | Rooms: party lines (always open, or at set hours that ring the members’ phones at opening), phone rooms with addresses (standup@host, dialable from any phone’s key), host mute/remove/lock, cross-server join; hold, instant 3-way (Add caller → Merge) and blind/attended transfer; a peer-to-peer mesh (≤ 4) or a relay (Cloudflare Realtime SFU, or LiveKit when self-hosting) with top-3 forwarding, idle drop and fair-use metering |
done (software); relayed rooms are encrypted in transit, end-to-end (SFrame) planned |
| P6 (C1) | Team and org spaces as a workplace phone system: owner/admin/member roles, searchable directory, extensions (companion and phone MENU → Dial ext), ring groups (simultaneous, sequential, round robin), business hours with after-hours actions, shared voicemail boxes (“heard by”), call log with CSV export, audit trail, transfer across households and servers inside the space; public lines (a ring group with its own address anyone may call without connecting, with a queue, voicemail and “call me back”; a call back nobody took shows on the phones as a missed call) (docs/workplace.md) | done (software) |
| Calls (0.7.0) | Mute on the phones (MENU 3) and M in the app; a mic check and microphone/speaker choice in the app; reconnecting with an ICE restart, a plain “connection lost” and a poor-connection note; call waiting; missed calls (kept per person or phone, on the phones’ MENU 5 and the app’s Home) with call back and redial (docs/phone-ux.md) | done (server, apps, browser phone, firmware 0.9.4; firmware tried in QEMU, not yet on a real board) |
| Notices | A space’s guardians (owner and admins in a team) post a short notice to its phones (“Bus is here”), with an optional recording: a chime and the text on the ready screen, lifting the handset plays it, a key clears it; it expires (an hour by default) (docs/notices.md) | done (server, apps, browser phone, firmware; not yet on a real board) |
| Add-ons | Any service that serves live voice over a call (an assistant, a radio, a notes taker), linked to your own account with an address on it, you+radio@host: it links like a phone pairs, says what it does (shown on its page in the app’s Add-ons tab), and only you can call it at that address; parts it offers for sharing you give to people, who call that part at its own address you+radio+listen@host (here or on other servers) and can stop its calls or give it back. Every add-on is treated as untrusted: an allow-list of messages, limits on calls and lines, calls marked as an add-on’s everywhere, kids’ phones never reached; off unless the server’s operator turns them on (ADDONS=on). The add-on bridge (sdk/python, Python, Apache-2.0) gives a service the calls as events and PCM audio, with echo and one-way radio examples (docs/add-ons.md) |
done (server, apps, browser phone, bridge, sharing; the hardware phone shows the label, not the share, and is not yet tested on a real board) |
| P5 | Interop tests in CI (two self-hosted servers and two Workers under wrangler dev, on every push) and a versioned federation spec, docs/federation-spec.md |
done |
| Versions | Servers advertise their software, federation versions and features and negotiate per peer (degrading in plain words); phones and servers exchange protocol ranges (UPDATE NEEDED on a too-old phone); v1 frozen by conformance vectors (tests/conformance/); CI runs this server against the previous release (server-v*) both ways |
done |
| Firmware | ESP32-S3 firmware (firmware/, ESP-IDF; changes in firmware/CHANGELOG.md): Wi-Fi and server setup from a phone, pairing, calls with two-way audio (Opus wideband, PCMU fallback, AGC, concealment, sidetone, echo measurement and canceller: docs/audio.md), leaving and playing voicemail, hold and transfer, extensions, Lounge phones, signed updates (off in source builds), encrypted storage, the phone check and self-test. The labs build (firmware/labs/, 0.0.0) adds the experiments above | 0.9.6: call audio (Opus at 16 kHz, the mic’s AGC, an adaptive jitter buffer and concealment, sidetone, echo test and canceller). 0.9.5: the wired network on hw v0.2. 0.9.4: mute, call waiting, missed calls and redial, reconnecting; the house intercom (signed and encrypted on the LAN), the chime and the daily check-in moved in from labs. Host tests, builds and QEMU tests (firmware/CHANGELOG.md); not yet on a real board. The v0.1 dev boards run the experimental labs build (0.0.0) for now, lightly tested; full testing waits on the Wi-Fi antennas (hardware/BRINGUP.md) |
| Hardware | A minimal 2-layer board (ESP32-S3, 12 hot-swap keys + hook switch, a 2.13” e-paper display module on a header, 3.5 mm jack + codec for an analog handset, piezo ringer, one status LED; USB-C power, no battery, NFC, speaker or hardware mute) in a 3D-printable base | v0.1 early dev board prototype (hw-v0.1, rev A): four phones built and working, lightly tested; expect a revision (we recommend board v1.0 for building your own); 3D-printable cases: the prototype box, a wall unit and the plush desk case |
Versions and changes: the server and apps in CHANGELOG.md (releases are tagged
server-vX.Y.Z), the firmware in firmware/CHANGELOG.md (fw-vX.Y.Z), the
hardware as hw-vX.Y releases; how they fit together:
openloungephone.app/project/versions/.
More: architecture, the phone’s UX, federation (and its spec), the public hub, add-ons, privacy, hardware.
Layout
Section titled “Layout”packages/protocol wire protocol (zod schemas) — the contract every device speakspackages/core pure domain logic shared by all backends and devicespackages/db SQL migrations + typed store (Cloudflare D1 and SQLite)packages/federation server-to-server signatures (RFC 9421, Ed25519), keys, /fed/v1 schemaspackages/server-app backend-agnostic HTTP API, connection gateway, household hubs, federationpackages/client browser helpers: socket, WebRTC call media, tonesapps/server-selfhost Node server (+ Dockerfile, compose.yaml with coturn)apps/server-cloudflare Worker + Durable Objects + D1 + R2, and the deploy scriptapps/cli `npx openloungephone`: deploy, self-host setup, status, doctorapps/device-web the phone in a browser (keys, LEDs, status strip, handset)apps/companion companion PWA for guardians, grown-ups and operatorsfirmware/ ESP32-S3 firmware (ESP-IDF), its simulators, and the labs build (firmware/labs)hardware/ schematic, board layout and core shell, all as codedocs/ architecture, federation (+ spec), hub, privacy, generated protocol referenceRepositories
Section titled “Repositories”| Repository | What |
|---|---|
| open-lounge-phone (this one) | the product: software, firmware, hardware sources, docs and tests |
| website | the project site, openloungephone.app, built from this repository’s docs |
| .github | the GitHub organization profile |
Try it
Section titled “Try it”npm installnpm startOpen the setup link the server prints, create your household, then open
http://localhost:8787/device/ in another tab. That’s the phone. Press Space to lift its
handset and it reads out a pairing code; enter it in the companion app, then call each other.
To run a real server, npx openloungephone selfhost init (Docker; see
docs/self-hosting.md — the Docker packaging has not been build-tested
yet) or npx openloungephone deploy cloudflare (your own Cloudflare account; see
docs/cloudflare.md). npx openloungephone doctor checks this machine.
Development
Section titled “Development”Requires Node 22.18+ (it runs the TypeScript sources directly).
npm installnpm test # unit tests (including a two-server federation test)npm run check # lint + typecheck + tests (what CI runs)npm run docs:protocol # regenerate docs/protocol.md after changing packages/protocolnpm run docs:federation # regenerate docs/federation-spec.md after changing packages/federationOLP_E2E_CLOUDFLARE=1 npx vitest run tests/e2e/cloudflare.test.ts # two local Workers (after npm run build)CI runs npm run check (including the v1 conformance vectors), both docs drift checks, and the
Interop workflow (two self-hosted servers, two Workers under wrangler dev, and this server
against the previous release in both directions, federating with each other).
License
Section titled “License”Software: AGPL-3.0-or-later, except the add-on bridge in sdk/python (Apache-2.0), so any service can use it. Hardware designs: CERN-OHL-S-2.0. If you run a modified Open Lounge Phone server for others, you must share your changes.
Proudly supported by unsubscribe.llc.