Your browser finally organized.
A local-first Chrome extension that turns tab chaos into a clean, searchable, self-organizing dashboard — and keeps Chrome's own tab groups organized automatically as you browse. No account. No cloud. No tracking. Everything runs on your device.
- Tab Dashboard — every open tab as a card: favicon, title, domain, last-active time, pin/mute state, grouped intelligently by category.
- Live native organization — new tabs are sorted into real Chrome tab groups (the colored ones in your actual tab strip) within a fraction of a second of opening, and everything gets re-sorted automatically when the browser starts. Toggle it off in Settings if you'd rather organize on demand.
- Smart Search — instant, debounced fuzzy search across title, domain, and URL.
- Local Heuristic Grouping — tabs are sorted into categories (Coding, AI, College, Shopping, Food, YouTube, Gaming, Finance, Research, Design, and more) using ~140 domain rules plus keyword fallbacks. No external AI API, no network calls, no data leaves your machine.
- Custom categories — right from any tab card, tag a domain with any category you want — including ones you make up, like "Food" or "Uni Projects." It's remembered permanently and applies instantly, no digging through Settings required.
- Drag-and-drop group overrides — drag any tab card onto a different group to manually recategorize it.
- Group Tabs Now — organize everything into native Chrome tab groups on demand, separate from —
- Remove Duplicate Tabs — closes duplicate tabs (same URL or same page opened twice), keeping the most recently active copy. Two distinct, clearly-labeled actions instead of one that does both.
- Expand / Collapse — every group can be collapsed individually, or all at once with Expand All / Collapse All.
- Session Manager — save the current set of tabs as a named session (e.g. "College", "Job Search") and restore it later in a new window.
- Workspace Mode — create named workspaces with notes, optionally linked to a saved session.
- Focus Mode — collapse the dashboard to just the category of your currently active tab (plus pinned tabs).
- Quick Switch (
Ctrl+Shift+K) — a Raycast-style launcher, available globally, to jump to any open tab by typing. - Reading Queue — set tabs aside to read later, and mark them unread / read / important.
- Tab Analytics — total tabs, tabs opened/closed today, top domains, category breakdown, and a 14-day activity chart — all computed locally.
- Smart Suggestions — inline nudges like "12 YouTube tabs open — archive them?" or "6 duplicate tabs found."
- Settings — theme (light/dark/auto), default grouping mode, custom category rules, stale-tab timeout, and a plain-language privacy panel.
- Performance safeguards — memoized tab cards, debounced search, and a "show more" expander that caps rendering at 30 cards per group so dashboards with hundreds of tabs stay responsive.
- Light / dark / auto theme, fully keyboard accessible.
npm install
npm run build- Open
chrome://extensions - Enable Developer mode (top right)
- Click Load unpacked
- Select the
dist/folder produced bynpm run build
npm run packageProduces release/tabbrain.zip, ready to upload to the Chrome Web Store Developer Dashboard.
TabBrain requests the minimum permissions needed and nothing more:
| Permission | Why it's needed |
|---|---|
tabs |
Read open tabs (title, URL, favicon) and switch/close/pin them |
tabGroups |
Create and label native Chrome tab groups, including live auto-grouping |
storage |
Save your sessions, settings, and reading queue locally |
sessions |
Support future recently-closed tab recovery |
windows |
Focus the right window when switching tabs, open saved sessions |
No host_permissions, no remote code, no analytics SDK, no network requests of any kind.
TabBrain is a Manifest V3 extension with three entry points, all built by a single Vite config:
dashboard.html— the main app, opened as a full browser tab when you click the toolbar icon. This is where the Dashboard, Workspaces, Sessions, Reading Queue, Analytics, and Settings views live.quickswitch.html— a small popup window opened by the background worker in response to the globalCtrl+Shift+Kshortcut, for switching tabs from anywhere without leaving your current page.background.ts— the MV3 service worker: opens/focuses the dashboard, opens the Quick Switch popup, records daily tab open/close counts for Analytics, and (when "Auto-group tabs live" is on) continuously mirrors each tab's category into a real Chrome tab group as tabs open and change, plus re-sorts everything on browser startup.
State flows one way: Chrome's tabs/tabGroups APIs → tabService (enrichment: domain, category, tracked open/active times) → a Zustand store (useTabStore) → React components. Nothing touches chrome.* APIs directly from a component; everything goes through src/services, which keeps the UI layer testable and the Chrome-specific code in one place.
Categories aren't a fixed enum — they're just strings. TabBrain ships with a curated set of "built-in" categories (each with a hand-picked color and icon), but any category name a user types into a custom rule works too, with a deterministically-generated color and a generic icon. Classification order, for every tab:
- Manual override — you dragged this exact tab into a different group (keyed by URL).
- Custom rules — a domain-to-category rule you created (Settings, or the tag icon on any tab card).
- Built-in domain rules — ~140 curated domain matches (
youtube.com→ YouTube,github.com→ Coding, etc). - Title keyword fallback — for unrecognized domains, a small set of keyword heuristics (e.g. "checkout" → Shopping).
- "Other" — nothing matched.
tabbrain/
├── manifest.json # MV3 manifest
├── dashboard.html # main dashboard entry
├── quickswitch.html # quick switch popup entry
├── assets/
│ └── logo.svg # source logo (blue-purple gradient, brain + tab)
├── public/icons/ # generated PNG icons (16/32/48/128)
├── scripts/
│ └── package-zip.mjs # zips dist/ for the Chrome Web Store
└── src/
├── background/ # MV3 service worker
├── dashboard/ # App shell + entry point for dashboard.html
├── quickswitch/ # entry point for quickswitch.html
├── components/ # UI, one folder per feature area
│ ├── Dashboard/ # DashboardView, AnalyticsView, ReadingQueueView, SuggestionsBanner
│ ├── Workspaces/ # WorkspacesView
│ ├── TabCard/
│ ├── GroupSection/
│ ├── SearchBar/
│ ├── Sidebar/
│ ├── SessionManager/
│ ├── Settings/
│ ├── QuickSwitch/
│ └── shared/ # Button, EmptyState, Skeleton, CategoryPicker
├── services/ # all chrome.* API access + business logic
│ ├── tabService.ts # tab enrichment, switch/close/pin/mute/group, manual overrides
│ ├── groupingService.ts # category/domain grouping heuristics + custom rules
│ ├── duplicateService.ts # duplicate cluster detection + resolution
│ ├── cleanupService.ts # "Group Tabs Now" and "Remove Duplicate Tabs" actions
│ ├── sessionService.ts # save/restore/rename/delete sessions
│ ├── workspaceService.ts # workspace CRUD, linked to sessions
│ ├── analyticsService.ts # local usage tracking + snapshot builder
│ ├── suggestionService.ts # Smart Suggestions generator
│ └── storageService.ts # typed chrome.storage.local wrapper
├── store/useTabStore.ts # Zustand store — single source of UI state
├── hooks/ # useLiveTabSync, useTheme, useDebouncedValue
├── constants/ # categories.ts (colors/domain rules), categoryIcons.ts
├── types/index.ts # shared domain types
├── utils/ # url parsing, fuzzy search, formatting
└── styles/globals.css # Tailwind + design tokens
TypeScript · React 19 · Vite · Tailwind CSS · Zustand · Framer Motion · Lucide Icons · Chrome Manifest V3 (Tabs, Tab Groups, Storage, Sessions, Windows APIs) · ESLint · Prettier
No Firebase, no backend — everything runs locally in the browser.
TabBrain collects nothing. There is no account, no cloud sync, and no telemetry of any kind. All settings, saved sessions, the reading queue, and analytics counters live in chrome.storage.local on your device only, and are removed if you uninstall the extension. See PRIVACY.md for the full policy.
Keyboard navigable throughout (Quick Switch supports arrow keys + Enter + Escape), visible focus rings on every interactive element, ARIA labels on icon-only buttons, native form controls respect the app's dark/light theme (via CSS color-scheme, so dropdowns are never an unreadable white box in dark mode), and color choices checked against WCAG AA contrast on both themes.
npm run dev # Vite dev server (for iterating on component code/styles)
npm run build # type-check + production build to dist/
npm run lint # ESLint
npm run format # Prettier
npm run package # build + zip dist/ into release/tabbrain.zipNote: npm run dev is useful for fast UI iteration, but Chrome extension APIs (chrome.tabs, etc.) are only available when the code is actually loaded as an extension — so functional testing of tab-syncing features requires npm run build + Load unpacked.
Planned for future releases:
- True virtualized scrolling (react-window or similar) for windows with hundreds of tabs in a single group, replacing the current "show more" cap
- Drag-and-drop manual tab reordering within a group (today's drag-and-drop only recategorizes)
- Cross-window session diffing ("this session vs. your current tabs")
- Exportable/importable sessions (JSON)
- Command palette actions beyond switching (close, mute, group, archive — all from Quick Switch)
- Optional, fully local on-device model for smarter categorization of unfamiliar sites (still no network calls — evaluating in-browser ML options)
Issues and pull requests are welcome. Please run npm run lint and npm run build before submitting a PR, and keep new Chrome API access inside src/services rather than calling chrome.* directly from components.
MIT
