Project

TapFold

An iOS and Android app that lets you save anything from the web, Instagram Reels, LinkedIn posts, X threads, articles, any URL, and instantly makes it searchable with AI.

Visit tapfold.com TapFold home screen

The problem

I kept saving things across too many places. Screenshots in my camera roll, links in Telegram to myself, bookmarks buried in Safari that I would never open again. The actual problem was not saving, it was finding. When I needed something I had seen a week ago, I had no way to get back to it quickly.

Most bookmark apps treat a link as just a URL. They store it, give you folders, and call it done. But a link to an Instagram Reel is not the same as storing a URL. The content lives behind a login wall. A week later you open the link and the Reel might be gone, or you are back to scrolling to find the moment you wanted. I wanted the app to actually capture the content, not just the pointer to it.

That is what TapFold is built around: save once from the share sheet, let AI do the tagging and summarization in the background, and make everything findable through natural language search later.

What it does

Save from anywhere

A native iOS and Android share extension lets you save from any app without opening TapFold. Tap share, pick TapFold, done. The extension posts to the API and exits immediately so you never leave what you were doing.

AI tagging and summarization

Every saved item goes through a background pipeline: scrape the content, transcribe if it is a video, then run tagging and summarization in parallel. By the time you open the app the item already has tags and a one-paragraph summary.

Semantic search

Search works on meaning, not keywords. Ask "that post about sleep and productivity" and it surfaces the right result even if those words are not in the title. This is what makes TapFold a proper AI bookmark manager rather than just a read-later app. Built on pgvector with HNSW indexing for fast cosine similarity lookups.

TapFold AI search screen

How it is built

This is a pnpm monorepo with three apps and one shared package. Every Zod schema lives in the shared package and both the API and the mobile app import from it, so the contract between client and server is always in sync and never duplicated.

Mobile
Expo SDK 54
API
Hono on Node
Database
PostgreSQL 16
Search
pgvector HNSW
ORM
Drizzle
Job queue
pg-boss
Scraping
Apify
AI
Groq + OpenAI
TapFold bookmark detail screen

Engineering decisions worth noting

Async pipeline with pg-boss

The save endpoint returns immediately with a pending status. All the heavy work, scraping, transcription, AI processing, embedding, runs as a job graph in pg-boss. This keeps the share extension fast and means the user never waits. I chose pg-boss over a separate queue like Redis because we already had Postgres and I did not want another dependency in production for what is essentially a queue.

HNSW over ivfflat for vector search

pgvector supports both HNSW and ivfflat indexes. ivfflat needs a full table scan during index build and its recall degrades as the table grows without rebuilding. HNSW builds incrementally and keeps consistent recall, which matters more for a personal collection that grows gradually.

Share extension and the App Group keychain

The iOS share extension is a separate process and cannot read the main app's Secure Store directly. The auth token is stored in a shared App Group container so the extension can pick it up, POST the URL to the API, and exit without ever launching the main app. Getting this keychain sharing right across extension and host app was the trickiest native setup in the project.

OTA updates via EAS with a server-side kill switch

JS-only changes ship as OTA updates through expo-updates without a new App Store submission. For breaking changes there is a version gate: the API returns a minSupportedBuild and latestBuild on every launch, and the app shows a hard or soft update prompt based on those values. Changing the gate requires only an API redeploy, not a mobile release.

TapFold share extension

What I learned

Building a mobile app from scratch is a different problem set than web. Native modules, code signing, Xcode project files that you do not touch directly, and the gap between Expo Go and a real dev client all add up quickly. The share extension alone took longer to get right than most features in the main app.

The AI pipeline was also more plumbing than intelligence. The interesting part was not calling an LLM, it was building the job graph that survives failures, retries gracefully, and does not double-process a bookmark if a webhook fires twice.

TapFold is live at:

tapfold.com