byte-pack

Byte Pack — Development Guide

This document explains the internal architecture of Byte Pack, how the modules connect, the reasoning behind key technical decisions, and notes for future phases.


Architecture Overview

Byte Pack follows a clean separation of concerns across four layers:

UI Layer        popup/ + settings/          What the user sees and interacts with
Logic Layer     core/                       Business logic, no UI dependencies
Orchestration   background/                 Wires everything together
Theming         ui/                         Visual system, independent of logic

The core modules have zero UI dependencies — they can be tested independently and reused across phases without modification.


Module Responsibilities

manifest.json

The MV3 extension manifest. Defines permissions, the service worker entry point, the popup HTML, and the settings page. Uses "type": "module" on the service worker to enable ES module imports across all core files.

background/service-worker.js

The backbone of the extension. Does not perform any logic itself — it listens for messages from the popup and delegates to the core modules. Keeping it thin makes it easy to extend without breaking existing functionality.

Supported message actions:

core/tab-scanner.js

Scans all open tabs in the current window and identifies which ones contain direct image files. Uses a two-step detection strategy:

  1. Fast path — checks the URL file extension against a known list. Zero network cost, instant result.
  2. Slow path — falls back to a HEAD request via content-type-checker.js for URLs that have no recognisable image extension.

Internal browser pages (chrome://, edge://, about:) are filtered out before either check runs.

core/content-type-checker.js

Sends a HEAD request (not GET) to a URL and inspects the Content-Type response header. Using HEAD is deliberate — it fetches headers only, with no file body, keeping the check lightweight. CORS failures are caught silently and return false — the tab is simply skipped.

core/downloader.js

Handles filename generation and download orchestration. Key decisions:

ui/theme.js

Handles OS detection, theme loading, saving, and applying. Key decisions:

popup/prepaint.js and settings/prepaint.js

Loaded as the first <script> in each HTML <head>. Reads the saved theme from localStorage synchronously before any rendering occurs and sets the correct background color on <html>. Prevents the white or wrong-color flash that would otherwise appear while the theme CSS file loads asynchronously. Inline scripts are blocked by MV3’s Content Security Policy — a separate file is required.

ui/themes/

Three CSS files that define the visual identity of each theme entirely through CSS custom properties prefixed with --pd-. The popup and settings CSS files never hardcode colors — they only reference these variables. Swapping themes requires no changes to layout or component styles.

Theme Inspiration Font
win11.css WinUI 3 / Fluent Design Segoe UI Variable
macos.css Apple HIG -apple-system / SF Pro
default.css Neutral system system-ui

Data Flow

Quick Save flow

User clicks Quick Save
        │
        ▼
popup.js sends QUICK_SAVE message
        │
        ▼
service-worker.js receives message
        │
        ▼
tab-scanner.js queries all tabs
        │
        ├── Fast path: URL extension check
        └── Slow path: content-type-checker.js HEAD request
        │
        ▼
downloader.js receives image tab list
        │
        ├── Generates timestamped filename
        ├── Calls chrome.downloads.download()
        └── Waits 50ms before next download
        │
        ▼
Result summary returned to popup.js
        │
        ▼
popup.js updates UI state

Theme load flow

Page opens (popup or settings)
        │
        ▼
prepaint.js reads localStorage synchronously
Sets correct background on <html> instantly
        │
        ▼
theme.js initTheme() called
        │
        ├── Checks localStorage (fast path)
        └── Falls back to chrome.storage.sync
        │
        ▼
applyTheme() injects <link> tag for correct CSS file
        │
        ▼
Page renders with correct theme, zero flash

Key Technical Decisions

# Decision Rationale
1 Manifest V3 Required for Chrome and Edge store submission. Service worker replaces persistent background pages.
2 ES Modules "type": "module" on the service worker enables clean imports across core files without a bundler.
3 HEAD requests for content-type Avoids downloading image bodies during tab scanning. Lightweight and fast.
4 Sequential downloads with 50ms stagger Guarantees unique millisecond timestamps. Imperceptible to the user.
5 Dual storage for theme chrome.storage.sync for cross-device persistence, localStorage for synchronous pre-paint access.
6 CSS custom properties for theming All three themes share identical component CSS. Only variable definitions differ.
7 Format conversion via Canvas/Blob Chrome Downloads API has no native format conversion. Canvas approach is client-side and dependency-free.
8 Settings as a full tab options_ui popup mode caused clipping and background window issues in Edge. Tab mode is cleaner and more standard.
9 Modular core architecture Core modules have zero UI dependencies. Easy to test independently and extend for Phase 2 and 3.

Phase 2 — Implementation Notes

When starting Phase 2, the following files are already stubbed and ready:


Phase 3 — Implementation Notes


Running Locally

  1. Clone the repository
  2. Open edge://extensions or chrome://extensions
  3. Enable Developer Mode
  4. Click Load unpacked and select the byte-pack/ folder
  5. After any code change, click the Reload button on the extension card

Future Design Considerations

Brand Identity & Custom Accent Colors

Currently the three themes use their respective platform default accent colors:

Once the Byte Pack brand identity is defined (logo, color palette), a full theming pass should be done across all three theme files to replace the platform defaults with Byte Pack’s own accent color. This should be done in one pass rather than incrementally to keep all themes consistent.

CSS system accent color (accent-color: auto) was considered but not implemented due to browser privacy restrictions preventing reliable access to the OS-level accent color value. Most users never change their system accent color anyway, so the platform defaults cover the vast majority of cases well.

Icon Set

The current icons in assets/icons/ are placeholder PNGs generated during initial development. They should be replaced with a proper branded icon set at the same time as the accent color update, keeping the visual identity consistent across the toolbar, popup, and store listing.