Skip to content
dg.dev
← all projects

2026 · updated 12 Sept 2026

tabsesh

Sixty tabs, one undoable command.

The problem

I kept ending up with 60+ tabs across three windows. Most tab managers are either a bookmarks-bar clone or a subscription with a login screen.

I wanted something that keeps everything in the browser's own bookmarks, works from the keyboard, and never quietly does something destructive: closing 40 tabs should be undoable, not a gamble.

How it works

  1. PopupFull-page appQuick overlay
  2. src/lib/core
  3. chrome.bookmarkstabs · tabGroups · alarmschrome.storage.local

Every entry point calls the same functions in src/lib/core, which has no Svelte in it at all. A bug fixed there is fixed in the GUI and the terminal at once, and neither can drift out of sync with the other.

The hard parts

  1. 01

    Timers that survive the service worker

    A Manifest V3 service worker can be killed at any moment, and a setTimeout dies with it. Focus sessions use chrome.alarms, the one timer that survives a restart, so a 25-minute session still fires.

  2. 02

    Testing APIs nobody fakes

    The fake extension APIs WXT recommends don't implement bookmarks or tabGroups at all, since most extensions never touch them. I wrote a small in-memory fake for just those two, built around what the code actually calls.

  3. 03

    Two bugs caught before release

    The 73 tests caught undoLastDelete restoring the wrong folder when two deletions landed in the same millisecond, fixed with a stable tie-break, and a bug in fake-browser itself, where tabs.remove() looked up a window by the tab's own id.

Decisions and trade-offs

Bookmarks as the database

Sync across devices comes free and there's nothing to migrate or back up. The cost: folder names must be unique across the whole tree, since commands look folders up by name.

Soft delete everywhere

rm moves folders to a hidden trash for 48 hours. A keyboard tool makes a fat-fingered command too easy; reversible by default beats a confirmation dialog nobody reads.

A user token instead of OAuth

Sharing a folder as a Gist uses a personal token scoped to gist only, which keeps the whole extension serverless.

Permissions only for what they're for

<all_urls> exists only for the overlay hotkey; alarms and notifications only for focus sessions. Each one is explained in the README.

What it doesn't do yet

  • No Firefox build yet, though WXT supports one; I've only tested Chrome.
  • The memory-freed estimate depends on chrome.processes, which not every Chromium build has; when it's missing, the number just doesn't show.