Keep everything, sort nothing.
A local-first Chrome extension for frictionless capture and semantic retrieval of web content. Save articles, images, videos, highlights, and more — then find them later with natural language search powered by on-device AI.
All processing, storage, and ML inference happen entirely in your browser. No account. No server. No data leaves your device.
- One-click capture — Save articles (clutter-free via Readability), images, videos, text highlights, products, and recipes from any page via toolbar icon or right-click menu
- Semantic search — Query your saved content in natural language (e.g. "blue living room inspiration") using CLIP embeddings and hybrid vector + full-text ranking
- Fully private — Everything stays in your browser; the CSP blocks all network requests except model weight downloads from a pinned CDN
- Works offline — No connectivity required after initial model download
- Top of Mind — Pin items to a priority strip for active projects and inspiration
- Focus Mode — Distraction-free Markdown editor with contextual access to your saved content
- Portable — Export your entire library as SQLite, JSON, or Markdown; optional AES-GCM encryption for backups
Saving an item triggers a two-phase pipeline:
- Phase 1 (instant, durable): Content is extracted and persisted to SQLite on OPFS with
status=pending_embedding. The card appears immediately in the side panel. - Phase 2 (async, recoverable): A CLIP embedding is computed on-device (FP16 via WebGPU for max quality, Q4 via WASM fallback for memory efficiency), then written atomically to SQLite, the HNSW vector index, and the FlexSearch full-text index.
Search runs entirely in the offscreen document: your query is embedded by CLIP, the top-50 results from a flat CPU vector index and FlexSearch are fused with Reciprocal Rank Fusion, filters are applied, and ranked items are returned — all in under 150ms for a 10k-item library.
| Layer | Choice |
|---|---|
| Extension | Manifest V3, Chrome Side Panel API |
| Bundler | Vite + @crxjs/vite-plugin |
| Language | TypeScript (strict) |
| UI | Preact + TailwindCSS |
| Storage | SQLite Wasm (@sqlite.org/sqlite-wasm) on OPFS |
| ML | Transformers.js — Jina CLIP v1 (swapniel99/jina-clip-v1), 512-dim, FP16 (WebGPU) / Q4 (WASM) |
| Vector index | Flat in-memory CPU (cosine dot-product), rebuilt from SQLite on wake-up |
| Full-text | FlexSearch, persisted to OPFS |
| Thumbnails | IndexedDB |
| Model weights | Cache API |
- Minimal network egress — CSP restricts
connect-srcto the pinned Hugging Face model mirror; image/thumbnail fetches go directly to source origins for display only, no user data is transmitted - No remote code — Transformers.js is bundled; no CDN scripts
- No account required — zero server-side component
- Sanitized HTML — all captured HTML is run through DOMPurify before storage
- Encrypted backups — AES-GCM with PBKDF2 (≥600k iterations), opt-in
Under active development. See docs/PLAN.md for the milestone roadmap (M0–M9).
| Milestone | Description | Status |
|---|---|---|
| M0 | Toolchain & repo scaffolding | ✅ Done |
| M1 | Messaging skeleton | ✅ Done |
| M2 | Storage layer (SQLite + OPFS) | ✅ Done |
| M3 | Capture pipeline Phase 1 | ✅ Done |
| M4 | Side panel shell UI | ✅ Done |
| M5 | ML runtime + CLIP | ✅ Done |
| M6 | Phase 2 indexing + job queue | ✅ Done |
| M7 | Hybrid search | ✅ Done |
| M8 | Portability + backup | 🔲 Next |
| M9 | Performance gates + RC | 🔲 |