A browser extension that opens an image lightbox when you use a configurable double-press shortcut while hovering an image.
Hover over an image and press your chosen shortcut twice to open a clean lightbox with quick zoom and pan controls. Customize the shortcut, control visibility, and overlay colors in Settings, and keep your preferences saved for future sessions.
- Configurable double-press activation shortcut on hovered images (
Ctrl + Ctrlby default) - Zoom controls (
-,+,Fit) - Toggle toolbar and close controls with
hby default while the lightbox is open - Mouse wheel zoom around the cursor
- Drag-to-pan when zoomed in
- Customizable toolbar and close button colors
- Customizable activation shortcut and controls-toggle shortcut
- Option to hide overlay controls by default
- Settings are saved for future browser sessions
- Activation shortcut is ignored while typing in editable fields
- Close with
Escor by clicking outside the viewer - Runs on most
http://andhttps://pages
If the default activation shortcut does not work well with your browser or system setup, switch to Shift + Shift or Cmd/Meta + Cmd/Meta in Settings.
Microsoft Edge includes a built-in Magnify image feature that can also uses Ctrl + Ctrl. If there is a conflict, either:
- Change this extension's activation shortcut in Settings
- Turn off Edge's Magnify image setting at
edge://settings/privacy/sitePermissions/allPermissions/magnifyImages
- Supports standard
<img>elements only - Top frame only; no iframe support
- No
background-image,canvas, orsvgsupport in this version - Does not run on restricted browser pages such as internal browser URLs
![]() |
![]() |
![]() |
![]() |
- WXT for extension development and cross-browser builds
- React 19 for the popup and options pages
- TypeScript 5 throughout the project
- Vitest with
jsdomand the WXT Vitest plugin for unit testing - pnpm for package management and scripts
- Manifest V3 configuration managed in
wxt.config.ts
Install dependencies:
pnpm installStart a Chromium or Firefox browser development build:
pnpm dev
pnpm dev:firefoxType-check the project:
pnpm compileBuild for Chromium or Firefox browsers:
pnpm build
pnpm build:firefoxCreate distributable zip archives:
pnpm zip
pnpm zip:firefoxWXT writes generated extension artifacts to .output/.
- Run
pnpm buildorpnpm dev. - Open your browser's extensions page, such as
chrome://extensionsoredge://extensions. - Enable Developer mode.
- Click Load unpacked.
- Select the generated Chromium build directory inside
.output/.
- Run
pnpm build:firefoxorpnpm dev:firefox. - Open
about:debugging#/runtime/this-firefox. - Click Load Temporary Add-on.
- Select the generated Firefox zip file inside
.output/(ends in-firefox.zip).
Run the full unit test suite:
pnpm testRun tests in watch mode during development:
pnpm test:watchGenerate a coverage report:
pnpm test:coverageThe test suite uses Vitest with jsdom, WXT's test plugin, and shared setup in src/test/.
.
|-- public/
| |-- favicon.ico
| `-- images/
| |-- icon-16.png
| |-- icon-32.png
| |-- icon-48.png
| `-- icon-128.png
|-- images/ # README screenshots and demo assets
|-- src/
| |-- components/ # shared React UI for popup/options
| | |-- CloseButtonSection.tsx
| | |-- ColorField.tsx
| | |-- KeyboardSection.tsx
| | |-- PreviewPanel.tsx
| | `-- ToolbarColorSection.tsx
| |-- entrypoints/
| | |-- content/
| | | |-- index.ts # content script orchestration
| | | |-- ActivationDetector.ts # double-press activation and shortcut matching
| | | |-- ActivationDetector.test.ts
| | | |-- ImageResolver.ts # hovered image lookup and source validation
| | | |-- ImageResolver.test.ts
| | | |-- SettingsManager.ts # stored settings loading and watchers
| | | |-- SettingsManager.test.ts
| | | |-- OverlayBuilder.ts # overlay DOM creation, theming, and teardown
| | | |-- ZoomController.ts # fit, zoom, pan limits, and button states
| | | |-- ZoomController.test.ts
| | | |-- DragController.ts # pointer-driven panning behavior
| | | |-- DragController.test.ts
| | | `-- style.css # lightbox styles
| | |-- options/ # React settings page
| | | |-- App.tsx
| | | |-- main.tsx
| | | |-- index.html
| | | `-- style.css
| | `-- popup/ # React popup entrypoint
| | |-- App.tsx
| | |-- main.tsx
| | |-- index.html
| | `-- style.css
| |-- hooks/
| | `-- useSettings.ts # shared settings loader for React entrypoints
| |-- test/
| | |-- createOverlayState.ts # shared overlay test state factory
| | `-- setup.ts # shared Vitest/jsdom setup
| |-- types/
| | |-- overlayTypes.ts # shared overlay state and event types
| | |-- formTypes.ts # options form value types
| | `-- colorTypes.ts # color-related shared types
| `-- utils/
| |-- colors.test.ts
| |-- settingsStorage.ts # WXT storage access and watchers
| |-- settings.ts # defaults, parsing, and validation
| |-- settings.test.ts
| |-- shortcuts.ts # shortcut constants and normalization
| |-- shortcuts.test.ts
| |-- theme.ts # CSS variable application for the overlay
| |-- colors.ts # CSS color validation helpers
| |-- formConversions.ts # options form <-> stored settings mapping
| `-- math.ts # shared numeric helpers like clamp
|-- vitest.config.ts # Vitest + WXT unit test configuration
|-- wxt.config.ts # WXT config and shared manifest metadata
`-- package.json # scripts, dependencies, and extension version







