Trust-sensitive correspondence
2026 · Live application · open source
Dear Friends
Making personal mail feel considered before anything is sent
I designed and built a personal correspondence workspace that collects addresses through trusted links, keeps meaningful dates close, and turns a private list into letters, labels, or deliberate digital delivery.

Quick scan
TL;DR
The shortest version: what changed, what shipped, what was verified, and where the proof stops.
Overview
Problem
Spreadsheets can hold addresses but do not create a considerate collection or correspondence workflow; sales CRMs bring the wrong incentives and tone.
Move
Designed one recipient-to-letter loop around visible trust: capability-backed collection, scoped previews, honest save states, and recoverable delivery.
Outcome
Shipped an open-source application spanning address collection, verification, contacts and groups, writing, exports, digital delivery, calendar planning, reminders, and maps.
Scope
Independent product strategy, interaction and visual design, full-stack engineering, security hardening, test automation, deployment, and product positioning.
Proof
- Build history
- 166 commitsThe inspected release branch spans March 5 through July 15, 2026 and is contained in the remote default branch.
- Verification
- 99 tests passedA disposable source copy passed all 19 Vitest files and TypeScript without modifying the sibling repository.
- Collection boundary
- 24-hour capabilityPublic address submission derives owner and optional group from an HMAC-signed, expiring server capability.
- Recipient boundary
- 14-day single useAddress verification tokens expire and are cleared after confirmation, correction, or opt-out.
01 · Context
Personal mailing lists sit between a spreadsheet and a sales CRM.
The people keeping holiday-card lists, family addresses, or community contacts need more than rows of data: they need an easy way for someone to share an address, a reminder before a meaningful date, and a path from a draft to something that can actually be sent.
Existing categories pull in opposite directions. A spreadsheet puts every step on the owner; a CRM turns friendship into pipeline management. Dear Friends started with a quieter premise: keep the list personal, ask as little as possible from recipients, and leave physical mail under the sender's control.
02 · The decision
Make trust visible at every handoff.
Share one link. Remember the date. Prepare something real.
The product is organized as three connected habits rather than a feature inventory. A friend adds an address without creating an account; the owner keeps the person and their dates in one private workspace; and the system prepares the label, letter, or eligible digital audience without pretending to mail a physical item.
That sequence also defines the interaction standard. Public mutations derive ownership from the server, high-consequence actions preview their audience, saved state follows actual persistence, and partial failures remain recoverable instead of collapsing into a generic success message.

Engineering noteA public link never supplies its own owner.
Public address collection is mediated by a short-lived signed capability. Verification is a separate single-use flow, and tenant relationships are constrained again in the database.
- Share capabilities are HMAC-signed, expire after 24 hours, and carry the server-resolved owner and optional group.
- Verification tokens are UUID-validated, expire after 14 days, and are cleared after confirmation, update, or opt-out.
- Supabase RLS, policies, and same-owner database triggers protect contacts, groups, calendar records, and share-slug relationships.
Try the handoff
Share an address without asking a friend to make an account.
This small local simulation follows the product’s public capability flow: a friend opens a personal link, shares the minimum information, and hands the next move back to the list owner.
Wants to mail you something.
“Can’t wait to send you something”
You won’t need an account. Your friend keeps the list private.
Interactive demo uses illustrative names and addresses. No address is submitted, stored, or sent.
03 · What shipped
A complete path from someone's address to a letter you can send.
The owner workspace combines searchable contacts, groups, delivery preferences, birthdays, notes, verification status, a geographic view, calendar events, subscription imports, and estimated mail-by dates. Public collection and verification remain account-free for recipients.
The writing path supports reusable Markdown drafts and first- and last-name merge tags. From the same server-derived audience, the owner can export Avery-ready address files, generate personalized letter PDFs, or confirm an email send to contacts explicitly marked digital.
Keep the person closer than the record

Engineering noteRecovery is part of the delivery contract.
The correspondence flow distinguishes a pending action from a persisted one and preserves enough server truth to recover without repeating successful work.
- Draft autosaves are serialized, expose saved and error states, and warn before leaving with unsaved changes.
- Bulk delivery previews come from the server-derived audience and require confirmation before email is sent.
- A partial digital send reports successful and failed counts and can retry only the failed addresses.
Security noteImported calendars are treated as an outbound network boundary.
Subscription URLs are resolved and validated before the server connects, then pinned to the address that passed validation.
- Only HTTPS URLs without embedded credentials are accepted.
- Local, private, mapped-private, multicast, and other unsafe IP ranges are rejected across redirects.
- Downloads have redirect, timeout, and one-megabyte size limits.
04 · Evidence
The evidence is the shipped workflow and the boundaries that keep it honest.
The inspected release branch contains 166 commits from March through July 2026 and is merged into the remote default branch. The repository includes the application, twelve ordered database migrations, public and authenticated routes, transactional email builders, scheduled jobs, CI configuration, and a live-application link.
In a disposable copy of the inspected source, TypeScript completed successfully and all 99 Vitest unit and security tests passed with caching disabled. Those tests cover schemas, capabilities, tenant boundaries, verification, calendar URL handling, reminder timing, export formatting, geocoding, and cron authentication.
No usage, revenue, retention, or correspondence-outcome analytics were found. The case-study claims are therefore limited to implemented behavior, repository and release history, passing source-level checks, and current product captures with illustrative data.
05 · Reflection
The trust model became clearer when the product stopped promising to do everything.
Earlier concepts blurred the boundary between preparing mail and mailing it. The stronger product contract is narrower: Dear Friends helps collect, remember, write, export, and send eligible email; printing, penning, stamping, and posting physical correspondence remain with the person who knows the recipient.
The engineering work reinforced the same lesson. Trust is not a tone-of-voice layer added at the end. It lives in signed capabilities, single-use verification, tenant-safe relationships, audience previews, persistence feedback, retry semantics, timezone handling, and fail-closed scheduled routes.
The next evidence gap is behavioral. A future iteration should measure where owners stop between collecting an address and preparing correspondence, and whether quiet reminders lead to a completed export or send without becoming another notification feed.