Inspiration

We all do the same thing: see something interesting online, screenshot it or hit "save," and never look at it again. Camera rolls full of recipes we'll never cook. Instagram saves we forget exist. Tweets bookmarked into the void. We're collecting more than ever and learning less from it. Recap started from a simple question: what if the stuff we save actually did something for us?

What it does

Recap turns every save into a private knowledge base, then writes you a Sunday digest of what you actually learned.

  • Save anything — paste a URL (IG, TikTok, X, YouTube, articles) or drop a screenshot
  • AI extracts what matters — title, summary, full caption / transcript / OCR
  • Multi-label categorization that learns your interests — one Reel about miso pasta lands in Recipes · Asian Fermentation · Quick Weeknight Meals simultaneously, and the system creates new categories as your tastes emerge
  • Sunday recap — "you saved 5 recipes, 2 Rust async deep-dives, 3 travel ideas" — written by Claude in your voice
  • Buy what you saved — crypto checkout on saved products via AllScale, 1% routed on-chain to charity via viem on Base, public donation log

It works two ways:

  • Push. Every Sunday, you get a personalized newsletter on what you actually learned this week — not a list of what you saved, but the throughlines in what you were curious about.
  • Pull. An AI assistant that knows your entire corpus. Ask "that recipe with the miso butter?" or "what have I been saving about distributed systems?" and it surfaces what you forgot you had.

How we built it

Stack:

  • Web — Next.js 16 + React 19 + Tailwind v4
  • DB — Turso (libSQL on AWS Oregon)
  • Storage — Vercel Blob for screenshots & IG thumbnails
  • AI — every model call routed through CLōD: OpenAI/gpt-oss-20B for chat/recap, voyage-3-large for embeddings
  • Hosting — Vercel, auto-deploys on push to main
  • Auth — anonymous cookie via Next 16 middleware (proxy.ts)
  • Crypto — AllScale Checkout (HMAC-SHA256 signed) + viem USDC transfers on Base

Per-platform extraction (each one is its own quirk):

  • TikTok → free oembed
  • YouTube → Data API + Innertube transcript
  • X/Twitter → cdn.syndication.twimg.com (the same endpoint twitter.com uses for embeds)
  • Instagram → og:tags scraped from public post HTML, with a paid scraper as the fallback path
  • Screenshots → tesseract.js OCR + LLM summary (locally)

Sponsors all integrated for real: Greptile (PR review), CLōD (model gateway), Nia (MCP indexing of Apple/Supabase docs), AllScale + Chain for Good (one feature, two prizes — crypto checkout with 1% on-chain donation).

Challenges we ran into

  • Instagram is broken-by-design for indie devs in 2026 — Basic Display API died Dec 2024, oEmbed was gutted Oct 2025, og:tags only work from residential IPs and Meta blocks Vercel's datacenter range. We ship a local-only rich extraction + a degraded cloud path
  • tesseract.js's worker child process can't bundle in Vercel — Cannot find module '..' from the worker script. Falls back to LLM-extracts-from-the-user's-note on production
  • Vercel serverless tears down functions the moment you respond — fire-and-forget background work doesn't run. Solved with Next 16's after() API for deferred ingest
  • Sync → async DB migration — moving from better-sqlite3 to @libsql/client meant making every DB call async and propagating awaits through 11 files. Mechanical but unforgiving
  • gpt-oss-20B leaks reasoning channel markers into JSON output — {"commentary to=assistant{... broke our parser. Wrote a balanced-brace JSON extractor + retry-with-stricter-prompt
  • libSQL strict typing — undefined in args throws "Unsupported type of value", differs from better-sqlite3's lenient handling. Wrote a nz() coercion helper
  • CLōD free-tier quota — only OpenAI/gpt-oss-20B and trinity-mini work without a credit bump; every Claude / GPT / Gemini returns 403. Made the model env-configurable so flipping is one line when credits land

Accomplishments that we're proud of

  • Full demo live on a public URL in under 6 hours — capture → categorize → recap, all working
  • Honest extraction strategy per platform — research-first approach (we wrote a 6.5k-word research doc before any code) meant we knew Instagram was dead before we built around it
  • Multi-label auto-discovered categorization — the LLM sees the user's existing categories on every ingest, picks all that apply, and proposes new ones when a clear theme emerges.

What we learned

  • Most social media platforms have actively hostile extraction stories. The research-first approach saved us hours of dead-end coding
  • Spotify Wrapped is the most underrated UX in tech. Applied to a learning feed instead of a music feed, it becomes the moat
  • Async migration is mechanical but unforgiving. Worth doing in one focused pass with type-checking after every file
  • Bundling native deps on serverless will always bite you. Tesseract, sharp, better-sqlite3 — each needs serverExternalPackages config and sometimes still fights you

What's next for Recap

  • Native iOS app + Share Extension — the original 6-week plan. Hit Share inside Instagram → Recap appears as a destination, one tap to save (the build plan is already written)
  • iOS 26 Visual Intelligence integration — long-press the screenshot button on any Reel → "save to Recap" → Apple delivers screenshot + on-screen text + ChatGPT description, no URL extraction needed
  • Real vision for screenshots — flip CLOD_MODEL=claude-opus-4-7 the moment CLōD credits land; the screenshot UX becomes 10× richer
  • Spotify-Wrapped-style share cards — a beautiful exportable recap image you can post back to IG/TikTok ("my week in 14 saves")
  • Email-claim flow — same cookie keeps working, but attaching an email lets workspaces persist across devices
  • Spaced-repetition surface — periodically resurface older saves ("remember this recipe from 3 weeks ago?") — turns the KB into active learning
  • Notion + Obsidian sync — research showed this is the #1 wedge for power users; a known-good integration is ~1 day of work
  • Open up to multi-user real teams — shared categories, collaborative recaps for couples / households / book clubs

Built With

  • cursor
Share this project:

Updates