Dearly is a free, no-login way to send someone a wrapped moment instead of a text — live at fromdearly.com, built solo, end to end. So this case study arrives the way the product arrives. Untie it.
Drag the tab • or tap to untie — the product's own words Opened. Drag it back to wrap it up again.
This didn't start as a product idea. It started as a failed errand: I wanted to send someone something that felt like more than a text, went looking for a way to do it, and gave up. Three things were wrong with everything I tried — and each one turned into a decision.
You send a thing into the void. The person receives it and there's nowhere to put what they felt about it — no reply, no acknowledgement, nothing back. For something whose entire purpose is connection, the connection was one-directional.
→ Became the hardest problem in the build. See Afterglow.Either a catalogue of hundreds of templates to scroll before you can start, or a single fixed card with your name dropped into it. Both fail the same way: the effort goes into picking instead of into what you actually wanted to say.
→ Three wraps. Not one, not a hundred.Make an account. Confirm an email. Now make them make an account. A gesture that should take two minutes turned into a form-filling session, and the feeling drained out somewhere around the password field.
→ No account, either side. One screen, one link.The sender never navigates anywhere. A live preview holds the left half the whole way down, and every choice on the right repaints it before they've finished making it — so “what will they actually see” is never a guess. Half-finished words and picked media survive a reload, and a chosen add-on won’t wrap empty — it has to hold a real photo or a playable note before the wrap moves on.

Who it’s between. Two named cards, not one form. The sender’s email exists only so a reply can find its way back — the receiver never sees it.

The wish. One open textarea, no blanks to fill, and a counter that reads “93 characters of you” rather than characters remaining.

The wrapping. Three, not one and not a hundred. Each is a full re-theme — picking one repaints the parcel on the left mid-thought.

Fingerprints, optional. A voice note and a photo, both opt-in: “pick one, both, or neither — the wish is complete on its own.”

The timing, then wrap. Now, tomorrow at 9am, or an exact moment — the option that forces real infrastructure behind the send button.

Choose how it lands. Wrapping mints two private links. Copy the link, send it anywhere sits level with email, not beneath it.
This was the hardest thing in the project, and it's invisible. Writing and wrapping a gift is a screen problem. Getting it to land — and knowing when it didn't, and why, and where it stopped — is a different kind of problem, and it took the longest to get right.
A gift is not a page view. If it silently fails to arrive, the sender doesn't just lose a feature — they think their person got something and was unmoved enough not to mention it. Silent failure is the worst possible bug in a product like this.
Anything that sends email on a stranger's behalf gets abused within days of going live. The standard fix is a CAPTCHA — which would mean asking someone to identify traffic lights in the middle of the most sincere thing they'll do all week. Cloudflare Turnstile sits on both doors instead — sending a gift, and sending a feeling back — and shows itself only when the traffic looks wrong; the cost tops out at a single checkbox. No grid of blurry crosswalks between a person and the thing they meant to say.
No form, no account wall, no install — they land on a page built only for them and pull the ribbon with their hands. What follows is every screen they actually meet, straight from the live product, in the order they meet it. The stages after the wish exist only because a voice note and a photo were attached — and each one gets a ground colour of its own. Two quiet courtesies hold the pacing: each stage’s media is preloaded before its reveal, and the first genuine untie is the one the record keeps — replaying never re-marks the gift as newly opened. At the end, Tuck this wish away saves the wish as a letter, not an export.
Arrived. A page built only for them — their name, the occasion, and an arrived stamp, before they have touched anything.
The wish. The note gets the screen to itself. No nav, no branding competing for the read, nothing hurrying them along.
The memory. A photo becomes its own stage on its own ground — presented as a polaroid, not an attachment.
The voice. “Press play. Stay awhile.” The one moment where the right thing to do is stop reading and listen.
The reply. It asks for one feeling back, routed privately to a sender whose address was never revealed.
Everything above is the ceremony. This is the crate it ships in — one app on Cloudflare, and the short list of things it talks to. The stack was chosen the way the wrapping was: as few pieces as possible, each with one job, nothing the ceremony doesn’t need.
One app renders both sides of the gift. Framer Motion runs the choreography — the untie, the lid, the staged reveals — as material behaviour, not decoration.
Create, deliver, media, reply, report, manage, delete. The gift is created first and delivered second — the split from part one lives here, as two different routes.
Every fact with a timestamp: gifts, deliveries, reactions, reports, retention cleanup. If the tracking page says it, a row here says it first.
Photos and voice notes, served only through the app’s own private routes — never from a public bucket.
On both doors, invisible until the traffic looks wrong — part one already made this argument.
Three transactional emails leave — the gift, the sender’s confirmation, the reply notification. Webhooks come back and write down what actually happened.
One the receiver opens, one the sender keeps. The links are the identities — the closing argument of part one is a line of architecture here.
Part one called silent failure the worst bug this product could have. This is how failure is made loud: the courier’s webhooks write the truth back onto the delivery — six states, each with a consequence — and the tracking page shows those stored facts, never a simulated progress bar.
Addresses get the same care as feelings. After delivery the system keeps a masked destination hint and the provider’s status, so a send can be retried without the stored address ever being shown again — and a suppressed address stops being written to at all.
The courier took the parcel. The clock starts.
Landed. The tracking page flips the moment the webhook does.
Still moving. Honest limbo beats fake certainty.
The address wasn’t real. The sender is told — and offered the link instead.
Marked as spam. The address joins the suppression list and Dearly stops writing.
The courier gave up. The gift survives — delivery retries, or gets handed over by hand.
Press send on most things and you get confetti and a dead end. Here the editable send screen folds away into a calmer post-send state, and a confirmation email carries the sender’s private management link — their only key back in. Behind that link: a page that says what has actually happened. Delivered, untied, expiring, deleted — every state on it is a stored fact from the courier and the ledger, never a simulated progress bar.
All the email is transactional — Resend carries it, webhooks grade it — but none of it reads like infrastructure. One system for all three: Dearly’s wordmark on a dark ground, a colour-blocked header, one message, one button. Personal, never promotional — the inbox is someone else's house, so the letters arrive dressed for the occasion.
The last stage of the ceremony offers a keepsake: Tuck this wish away saves the wish as a small paper object with a folded corner — a letter, not a PDF export with a timestamp. The gift expires in ninety days; the letter is the part that was always meant to outlive the link.
No accounts means access is a capability: whoever holds the link holds the gift. That tradeoff isn’t buried in a policy PDF — it’s written in the product’s own voice at fromdearly.com/trust, and every promise on that page has machinery behind it.
One press on the management link. No support ticket, no thirty-day limbo, no “deactivated” that secretly means archived. The receipt:
Verified in production rather than assumed: after a delete, both links die, the rows are gone, and the media routes return nothing. The page below is what a dead link looks like — the product’s voice, not a 404.
Expired, deleted, or never real — same kind page
There’s a first-party event when a gift is started, wrapped, sent, opened, replied to, kept. There is no event that knows who did it or what it said. The numbers can answer does the ceremony work — and cannot answer who stood in it.
Plain first-party events, stored like everything else.
No ad pixels, no profiles, nothing third-party.
Uploads that die mid-flight, media too big to keep, a courier outage, a webhook that never arrives, a link opened after its ninety days — each has a written script instead of a stack trace. The rule from part one holds at the edges too: the moment survives the outage.
The ceremony also holds when nobody is watching it with a mouse on a big screen: keyboard all the way through, visible focus, status and errors announced to screen readers, contrast and touch targets checked, and reduced motion honoured without gutting the reveal — the ribbon still unties, it just doesn’t make anyone wait. Desktop, phone, tablet, and the in-app browsers links actually get opened in.
One person, about a month, start to live. Scope was the whole game — three things came out along the way, for two different reasons, and both reasons are worth being straight about.
Money goes back on the table first — it's the one cut that was forced rather than chosen, and it's the difference between a thing people love and a thing that can sustain itself. SMS follows. Both are additive: neither requires an account, so neither breaks the one rule the product is actually built on.
Every messaging product solves replies with identity — two accounts and a thread between them. Take accounts away and there is nothing left to hang a conversation on. The answer was to make the links themselves the identities: wrapping mints two private URLs at once, one the receiver opens and one the sender keeps, so a feeling can travel back between two people who never signed up for anything.
Every stage gets a ground of its own — pink to arrive, paper for the wish, blue for a memory, coral for a voice, yellow to ask for something back. The page you just scrolled ran the same arc. It's your turn.
Wrap one for someonefromdearly.com · free · no account for either of you