Skip to content

discorporate/container-home-page

Repository files navigation

Container Home Page

A Firefox extension that replaces the new tab page with a grid of container-organized links — your bookmarks, sorted by the containers you already use.

Features

  • One-click container tabs — click any link to open it in the right container, no extra steps
  • Right-click any tab to add it to your home page instantly
  • Drag and drop to reorder containers and links however you like
  • Firefox Sync — your home page follows you across devices automatically
  • Site icons — optionally fetch favicons via Icon Horse, off by default for privacy
  • Light, dark, or auto theme with optional per-device override
  • Minimal permissions — no tracking, no analytics, no access to your browsing

Development

Prerequisites

  • Node.js
  • Firefox 140+

Setup

npm install

Build

npm run build

Bundles TypeScript sources into dist/ (worker + page + static assets).

Run (temporary install with auto-reload)

npm start

Or for live rebuild + run:

npm run dev

Lint

npm run lint

Package

npm run package

Produces a .zip in artifacts/.

Testing

Unit Tests

npm test

Runs Vitest against the pure model (mutations, reconciliation, quota, write planner, orchestrator). No browser needed — all logic is tested with in-memory mock storage.

npm run test:watch

Runs Vitest in watch mode for development.

Browser Tests

Browser tests use Playwright to run the built extension in Firefox.

npm run build
npm run test:browser

Note: Browser tests require PLAYWRIGHT_FIREFOX_EXT=1 to actually run (they skip by default). Firefox extension loading in Playwright uses internal APIs that may not be available in all environments.

Testing with a Firefox Profile

To test against an existing Firefox profile (e.g., one with containers already configured, or with Firefox Sync enabled):

FIREFOX_PROFILE_PATH=/path/to/profile npm run test:browser

Finding your profile path:

  1. Open Firefox
  2. Navigate to about:profiles
  3. Copy the "Root Directory" path for the profile you want

Creating a dedicated test profile:

firefox -CreateProfile "extension-test"

Then find its path in about:profiles or under:

  • Linux: ~/.mozilla/firefox/
  • macOS: ~/Library/Application Support/Firefox/Profiles/

Using a profile for manual testing:

npm run build
web-ext run --source-dir=dist --firefox=firefox --firefox-profile=/path/to/profile --keep-profile-changes

The --keep-profile-changes flag preserves storage data between runs — useful for testing sync scenarios or migration from existing data.

Without a profile: Playwright creates a temporary profile with containers enabled via Firefox preferences. Tests create their own containers via the contextualIdentities API. The temp profile is discarded after the test run.

Architecture

The extension uses a Manifest V3 service worker as the sole authority for state mutation and sync reconciliation. The new tab page is a thin view that reads storage.local and sends mutations to the worker via runtime.sendMessage.

  • Worker writes storage.local and storage.sync
  • Page reads storage.local directly and builds DOM
  • Sync reconciliation uses presence-wins union with tombstones for deletes
  • Dirty flags ensure pending sync writes survive worker termination
  • No conditional sync/no-sync logic — same code paths regardless of Firefox Sync status

Permissions

Permission Why
contextualIdentities Query Firefox containers
cookies Required by the contextualIdentities API
tabs Open links in container tabs
menus "Add to home page" tab context menu
storage Persist link/container configuration, Firefox Sync

Author

Jason Kirtland

License

MIT

About

Firefox new tab page extension for multi-account containers

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages