← Projects · 2026-07-16

latent

A phone-photo editor with a 'develop it later' option. Film-style effects in the browser, then download instantly or send it off to develop behind a randomized hours-to-days delay.

Live sitelatent.dev.xplwd.com → Repoexplewd/latent →

Highlights

  • All editing happens client-side on <canvas> — grain, vignette, halation, and light-leak overlays, plus a few 'vibe' presets (expired warm, cross-processed, faded) — nothing touches the server until you ask it to
  • Two finishing paths off one editor: instant download (client-only, optional share link), or 'send to develop' — uploads the result and gates the link behind a randomized delay, same idea as getting real film back
  • Named after the latent image — the real photographic term for a picture that exists on exposed film but stays invisible until developed
  • No accounts, no e2e encryption needed — nothing stored is sensitive, and the whole point is a link anyone can open, so the backend is simpler than wisp despite doing more
  • Reuses wisp's blob + SQLite metadata + TTL-sweep pattern rather than inventing new storage, with separate configurable retention for the instant-share vs. delayed-develop paths

A small, mostly-for-fun webapp: upload a photo from your phone, apply film-style effects in the browser, and either keep it or send it off to “develop.”

The instant path is a normal editor — grain, vignette, halation, light-leak overlays, and a few one-tap presets, all computed on <canvas> with nothing sent anywhere until you explicitly download or generate a share link. The delayed path is the silly, on-brand part: “send to develop” uploads the edited image and hands back a link immediately, except the link won’t actually resolve to the photo until a randomized delay — hours to days — has passed. Getting your photos back later, like real film, for no practical reason beyond it being a fun mechanic.

No accounts anywhere; a link is the only credential a photo has, same philosophy as wisp. Unlike wisp, none of this needs to be encrypted — nothing stored here is sensitive, and the entire point of the delayed path is a link other people can open — so the backend ends up simpler despite handling more than a pure “upload and forget” flow: blob storage plus SQLite metadata plus a background sweep, same shape already proven out by wisp, just with a develop_at gate instead of a confirm-token delete.