Mindful Tabz is an open-source browser extension designed for digital well-being. It helps you track your screen time, set daily limits for specific domains, and organize them into groups to maintain focus.
Mindful Tabz is built on the philosophy that your data belongs to you.
- No External Servers: Your browsing habits and limits are stored locally on your machine using
chrome.storage.local. - Open Source: Build and use your own version. Auditable, transparent, and private by design.
- Offline First: Works entirely without an internet connection.
- Site Blocking: Set daily and session-based time limits for distracting websites.
- Resource Groups: Group domains (e.g., "Social Media") and set a collective time quota.
- Real-time Analytics: Track exactly where your time goes with live-updating charts.
- Beautiful UI: A modern, dark-themed interface built with React and Tailwind CSS.
The project uses React, TypeScript, Vite, and Tailwind CSS v4, with a layered architecture:
src/
├── types/ # Shared TypeScript interfaces (Site, Group, etc.)
├── browser/api.ts # Single re-export of webextension-polyfill (use instead of chrome.*)
├── lib/ # Core business logic — StorageEngine, FocusTracker, DomainNormalizer
├── hooks/ # useStorageState, useSites, useGroups
├── components/ # Shared UI atoms — ProgressBar, TabNav, AddSiteForm, SiteCard, GroupCard
├── screens/
│ ├── popup/ # Popup views: ScreenTimeView, SitesView, GroupsView
│ ├── dashboard/ # Dashboard views: StatsView, BlockListView, GroupsView, SettingsView
│ └── blocked/ # BlockedScreen
├── App.tsx # Thin wrapper → PopupRoot
├── dashboard.tsx # Entry point → DashboardRoot
├── blocked.tsx # Entry point → BlockedScreen
└── background.ts # Service worker — tab tracking, alarms, blocking
manifests/ holds browser-specific manifest overrides merged at build time.
- Node.js v18+
- npm
npm installnpm run devThen load the extension in Chrome:
- Open
chrome://extensions/ - Enable Developer mode
- Click Load unpacked → select the
dist/chromefolder - After code changes, click the reload icon on the extension card
npm run dev:firefoxnpm run build:chrome
# Output: dist/chrome/Load in Chrome: chrome://extensions/ → Developer mode → Load unpacked → dist/chrome/
npm run build:firefox
# Output: dist/firefox/Load in Firefox: about:debugging → This Firefox → Load Temporary Add-on → select dist/firefox/manifest.json
To package a signed .zip for Firefox Add-ons (AMO):
npm run package:firefox
# Output: dist/packages/Safari requires Xcode and macOS:
npm run build:safariThis builds the extension and runs Apple's safari-web-extension-converter to generate an Xcode project in safari-xcode/. Open that project in Xcode to build and sign for the App Store.
npm run build:allAll browser API calls go through src/browser/api.ts (a re-export of webextension-polyfill), which normalizes browser.* across Chrome, Firefox, and Safari — never use chrome.* directly.
Browser-specific manifest fields live in:
manifests/manifest.base.json— shared fieldsmanifests/manifest.chrome.json— Chrome overrides (service_worker)manifests/manifest.firefox.json— Firefox overrides (scriptsarray,browser_specific_settings.gecko)
vite.config.ts merges base + browser override at build time based on the BROWSER env var.
Mindful Tabz is an evolving project. Contributions are welcome — bug fixes, new features, or UI improvements. Feel free to open a PR.