Message in a Bottle
Letters to your kids, sealed until the day they're old enough
Overview
Write letters to your children that stay sealed until a specific day. A parent signs in, adds a child with a birthday and a bottle timer, and writes to them. The bottle cannot be opened until the child reaches the age set on their profile, at which point a private self-authenticating link lets them read it without needing an account.
Sealing is final by design: once a letter is sent, the author can never view, edit, or delete it.
Key features
- Encrypted at rest
- A letter's title and body are encrypted at the application layer before they reach Postgres. The key lives outside the database, so a database dump on its own reveals nothing.
- Fail-closed decryption
- With no key configured, reading an encrypted letter or writing a new one fails loudly rather than silently storing or serving plaintext.
- Sealing is irreversible
- Once sent, a letter can never be viewed, edited, or deleted by its author. The guarantee is the point of the product.
- Time-locked by the child, not the letter
- Each child has a required bottle timer - an age older than they are now - and every letter to them opens on that schedule.
- Self-authenticating open links
- A child opens their bottles through a private tokenised link, with no account and no sign-in.
Screenshots
Parent dashboard listing sealed bottles, with a prompt to pick a child and start a new letter. The child's photo and name are blurred.
The letter composer, with a title field, a child selector, and a rich text body. The draft text is blurred.
A child's view once the bottles have unlocked, showing a letter from their parent. The child's photo and name are blurred.
The still-sealed view a child sees before the unlock date, with a countdown and a note that two letters are waiting. Name and dates are blurred.
Stack
- Next.js
- TypeScript
- Prisma
- PostgreSQL
- Auth.js
- Vercel Blob
- Tailwind CSS