English | Italiano
A Firefox extension that saves and restores browser working sessions. Each session captures open tabs and their scroll positions, and restores them in a dedicated window with automatic sync.
| Light | Dark |
|---|---|
![]() |
![]() |
Install from Firefox Add-ons (AMO)
- Save all tabs from the current window as a named, color-coded session
- Restore sessions in a separate window with scroll position preserved
- Auto-sync: restored windows track tab changes (add, remove, navigate) and update the session automatically
- Tag sessions with labels for organization, searchable from the filter bar
- Export all sessions (or a single one) as JSON for backup and migration
- Import sessions from a JSON file with validation and duplicate name handling
- Search and filter saved sessions by name or tag
- Inline rename with automatic duplicate handling
- Undo support on destructive actions (delete) via toast notification - works even if the popup is closed
- Storage usage indicator in the popup footer
- Dark and light theme following system preference
- Keyboard shortcuts: Ctrl+Shift+S (quick save), Ctrl+Shift+W (open popup)
%%{init: {'theme': 'default'}}%%
flowchart LR
popup["Popup UI"]
bg["Background Script"]
cs["Content Script"]
store["browser.storage.local"]
popup -- "message passing" --> bg
bg -- "get/restore scroll" --> cs
bg -- "CRUD + auto-sync" --> store
class popup,bg core
class store data
class cs engine
classDef core fill:#2563eb,stroke:#1d4ed8,color:#fff
classDef data fill:#d97706,stroke:#b45309,color:#fff
classDef engine fill:#059669,stroke:#047857,color:#fff
The extension uses Firefox's Manifest V2 API with three layers:
- Popup renders the session list, handles user interactions, and sends commands to the background script via
browser.runtime.sendMessage. - Background (event page, non-persistent) manages session CRUD, tracks restored windows for auto-sync, and coordinates scroll capture/restore.
- Content script runs on all pages to read and restore scroll positions on demand.
sequenceDiagram
participant U as User
participant P as Popup
participant B as Background
participant C as Content Script
participant S as browser.storage
U->>P: click "Save session"
P->>B: sendMessage(save-session)
B->>C: get-scroll (per tab)
C-->>B: {x, y}
B->>S: store session + index
S-->>B: ok
B-->>P: {success, session}
P-->>U: session in list
U->>P: click "Restore"
P->>B: sendMessage(restore-session)
B->>S: read session
B->>B: create window + tabs
B->>S: store pending scroll map
B->>C: restore-scroll (on tab load)
B-->>P: {success}
.
├── background/ # Session logic (modular)
│ ├── validation.js # Constants, input sanitization, URL and tag validation
│ ├── storage.js # Low-level storage read/write helpers
│ ├── session-crud.js # Save, restore, delete, rename, update, tags
│ ├── auto-sync.js # Tracked window sync, scroll restore, event listeners
│ ├── export-import.js # JSON export/import with validation, storage stats
│ └── background.js # Message listener, deferred delete, keyboard shortcuts
├── content/
│ └── scroll-capture.js # Scroll position get/restore via messages
├── popup/ # Extension popup UI
│ ├── popup.html # Popup markup
│ ├── popup.js # Session list, save form, context menu, inline rename
│ ├── popup.css # Light/dark theme styles
│ ├── tags.js # Tag input, tag editor modal
│ ├── export-import.js # Export/import UI, storage stats display
│ ├── search.js # Real-time session filtering by name and tags
│ ├── toast.js # Toast notifications (undo and informational)
│ └── ui-utils.js # Shared helpers (escapeHtml, formatAge, colors)
├── icons/ # Extension icons (16/32/48/96/128px)
├── tests/ # Jest unit tests (jsdom)
├── manifest.json # Extension manifest (Manifest V2)
└── package.json # Dev dependencies and scripts
- Firefox 91 or later
- Node.js 18+ (development only, for linting and tests)
- Clone the repository:
git clone https://github.com/AndreaBonn/firefox-session-snapshot.git
cd firefox-session-snapshot- Install dev dependencies:
npm install- Load the extension in Firefox:
- Open
about:debugging#/runtime/this-firefox - Click "Load Temporary Add-on..."
- Select
manifest.jsonfrom the repository root
- Open
The extension stays active until Firefox is closed. Repeat step 3 after restarting.
| Command | Description |
|---|---|
npm test |
Run tests (Jest, verbose) |
npm run test:coverage |
Run tests with coverage report |
npm run lint |
Lint with ESLint |
npm run lint:fix |
Lint with auto-fix |
npm run format |
Format with Prettier |
npm run format:check |
Check formatting |
Tests use Jest with jsdom environment, located in tests/. Test files mirror source modules:
background.test.js- session CRUD, message handler, auto-syncpopup.test.js- UI rendering, user interactionsscroll-capture.test.js- content script behaviorsearch.test.js- filtering logictoast.test.js- toast notifications and undo
Input validation, URL filtering, and output escaping are implemented across the extension. For details and vulnerability reporting, see SECURITY.md.
Released under the Apache License 2.0. See LICENSE.
If you found Session Snapshot useful, consider giving it a star on GitHub - it helps others discover it.

