A Chrome extension

Tab Piles

Save a whole browser window as a named pile. Switch piles without losing a single tab.

Coming to the Chrome Web Store

The desk

Pile it. Pick it back up.

This browser window is a mess. Hit Pile it, then click any pile to bring its tabs back.

tabs
12 tabs

     

    On the desk

    3 / 10 piles

      Illustrative data. Every title and note here is made up, and nothing leaves your browser. The real extension saves actual windows into IndexedDB.

      Filing system

      What goes in which drawer

      Free

      Local-first

      • Save a window to a pile with one shortcut.
      • Restore it to a fresh window, tabs where you left them.
      • Tags, rename, archive. Up to 10 active piles.
      • Cmd+K search across every pile and tab.
      • Piles untouched for 30 days move to the archive.
      • No account. The free tier never contacts a server.
      Pro

      $5/mo · $40/yr · $79 lifetime

      • Cloud sync between your devices.
      • A note on each tab, saying what it was for.
      • Full-text search over the pages you saved.
      • No login. Your license key is your account.
      Snapshots

      The real thing

      The extension's side panel, captured from a demo profile.

      The Tab Piles side panel listing four piles with tags and tab counts, and a 4 of 10 pile counter.
      The pile list: names, tags, tab counts and the 10-pile meter.
      One pile open, showing an editable name, tag chips, a Restore all button and its five tabs.
      One pile open: rename it, edit tags, restore all five tabs.
      The Cmd+K palette after typing granul, listing one matching pile and three matching tabs.
      Cmd+K mid-search: one pile and the tabs that match.
      The note

      Why I built it

      A browser window is where a lot of thinking happens. When the thread goes cold, the tabs pile up, and closing them means losing the trail. Tab Piles saves the whole window under a name so you can drop it and come back later.

      I built all of it end to end. The extension, the license and sync server, and the sales page are three separate repos. The free tier never talks to a server. Paid features sit behind a license key, with no login.

      Right now the code is finished and the Chrome Web Store submission is the next step.

      How it's builtstack · architecture · hard problems
      TypeScriptReact 18ViteChrome MV3Dexie / IndexedDBCloudflare WorkersHonoD1Lemon SqueezyVitest

      Architecture

      • Three repos. The extension (side panel, popup, service worker), a Cloudflare Worker for licenses and sync, and a static sales page.
      • Piles and tabs live in IndexedDB through Dexie. Free users never hit the network.
      • The Worker exposes /activate, /validate, /deactivate, /sync and /health, backed by D1.
      • Lemon Squeezy is the merchant of record. The license key is the account.
      • Pro checks go through one function, so a feature is either gated or it isn't.

      Problems worth the drawer

      • A clean free install. Snapshot search needs to read pages. The scripting and all-sites permissions are optional and requested only when a Pro user turns capture on, so the free install never shows the "read your data on all websites" warning.
      • Sync with no shared clock. Sync is last-write-wins by the client's clock. The trade-off is written down: devices more than 5 minutes apart can silently lose a write. A known pile-id collision on offline creates is also logged for a later release.
      • Licenses that survive bad wifi. The license is cached and rechecked after 24 hours. If the server can't be reached and the last good check was under 14 days ago, Pro stays on.
      • Searchable pages, bounded. Each tab's text is captured at save time and cut off at 50 KB, then fed into the Cmd+K search with a bit of context around each match.

      27 commits across 3 repos · 21 tests · public repos · not yet on the Chrome Web Store