Write and send email. Never an inbox.
Lamp is a send-only Gmail desk. Open it and you are on a blank sheet — no feed, no unread count, no 1am ambush. Built first for the Daylight Computer DC-1 (portrait, paper-like display), and as a PWA you can install anywhere.
Analog letter is on by default: wax seal to send, clock to hold until morning, paper, stamps, a letter book instead of Sent. Turn it off from the ⋮ menu if you just want a quiet modern composer.
- Blank composer on launch. No inbox, ever.
- Send through your Gmail (
gmail.sendonly — it cannot read mail). - Google Contacts autocomplete, the way Superhuman just has them.
- Android / PWA share target: a Chrome tab, a screenshot, a PDF — title goes in the subject, link in the body, files as clips or inline photos.
- Drafts that autosave. You do not lose a letter if the page dies.
- Hold until… five morning/lunch/dinner/Monday slots (with 8:00–8:30 jitter) plus a custom picker. Honest about Daylight sleep: the radio is off in a bag, so we promise the next time this desk is awake after that hour, not a fake 8:17am.
- Letter book (last 8 hours of what this desk sent), unfinished drafts, loft (queued / offline / stuck). Follow up a thread without opening Gmail.
- Rich text: bold, italic, underline, mild highlighter, lists, Docs-style
-/1.autoformat. Inline photo vs envelope attachment. “Did you mean to send without the enclosure?” - CC / BCC / Cc me. Undo send (8 seconds).
- Optional, default off, behind ⋮: voice dictation, iA Writer focus, pigeon post (Slowly-style delay), night, second share chip “To myself”.
npm install
cp .env.example .env
# paste a Google Cloud OAuth Web client ID into VITE_GOOGLE_CLIENT_ID
npm run devThen open the printed local URL, Allow Gmail + Contacts, write a letter.
- Google Cloud Console → create an OAuth Web client.
- Enable Gmail API and People API.
- Authorized JavaScript origins = wherever you host Lamp (and
http://localhost:8080for local). - Scopes:
gmail.send,contacts.readonly,contacts.other.readonly,userinfo.email,userinfo.profile.
There is no refresh token in the PWA path. GIS access tokens last about an hour. Sending later still needs the desk awake and a valid Allow.
A debug APK lives at public/lamp-debug.apk (~6 MB). Sideload on a DC-1 / Android tablet.
That shell gives you:
- two share-sheet chips: Lamp and Lamp — To myself
- a loft ping when Wi-Fi comes back after sleep
The letter UI is still the web desk. First launch asks for the HTTPS address of your published Lamp.
Native sources: android/.
TanStack Start, React 19, Tailwind 4, Zustand, Gmail GIS, IndexedDB drafts, PGLite (or Postgres if DATABASE_URL is set).
Personal daily-driver, mid-flight. Outlook, image markup, and a compose-only messenger (Beeper-shaped) are parked. Scheduled send is on-device, not Gmail’s cloud — see the in-app Desk note.
MIT. Built with Anjan on a Daylight.