Shipping a Chrome Extension in One Week
How I built and published a Chrome extension from concept to Chrome Web Store in a single week, using WXT for MV3 compliance, a site adapter pattern for extensibility, and Shadow DOM for style isolation.
When Astro Advanced Analytics needed a browser extension to complement their product analytics platform, the timeline was aggressive: concept to Chrome Web Store in the shortest time possible. I shipped it in one week. Here’s the technical approach that made it possible.
Choosing the Right Framework
Manifest V3 (MV3) is Chrome’s current extension platform, and it introduces significant constraints compared to V2: service workers instead of background pages, stricter CSP, and new permission models. Rather than fighting these constraints manually, I chose WXT (Web Extension Tools), a framework specifically designed for MV3 development. WXT handles the manifest generation, hot module replacement during development, and cross-browser compatibility.
The Site Adapter Pattern
The extension needed to work across multiple e-commerce sites, each with different DOM structures. Rather than writing site-specific scraping logic inline, I designed a site adapter pattern. Each adapter implements a common interface: getProductTitle(), getPrice(), getCategory(), etc. The extension detects which site the user is on and loads the appropriate adapter. Adding support for a new site means writing a single adapter file — no changes to the core extension logic.
interface SiteAdapter {
matches(url: string): boolean;
getProductData(): ProductData | null;
getPageType(): 'product' | 'category' | 'search' | 'other';
}
Shadow DOM for Style Isolation
The extension injects UI elements into the host page (overlays, panels, tooltips). Without isolation, the host page’s CSS would break the extension’s styling and vice versa. I used Shadow DOM to create a fully isolated rendering boundary. The extension’s UI lives inside a shadow root attached to a custom element, so its styles never leak out and the host page’s styles never leak in.
Typed Messaging
Communication between content scripts and the background service worker uses typed message passing. Every message type has a corresponding request/response type pair, enforced at compile time. This eliminates an entire class of runtime errors where you send a message expecting one response format but get another.
Google Sheets Integration
One of the key features was exporting product data directly to Google Sheets. This required OAuth 2.0 integration within the extension context, which is notoriously tricky. The extension uses Chrome’s identity API for the OAuth flow, then calls the Google Sheets API to append rows to a user-specified spreadsheet.
Prefetching for Instant UX
Product data can be expensive to extract from complex pages. To keep the UI feeling instant, the extension prefetches product data as the user navigates. When they hover over the extension icon or trigger the overlay, the data is already available — no loading spinner, no delay.
Results
The extension shipped to the Chrome Web Store in one week with an active release cycle. The site adapter pattern has proven its value: adding new site support takes hours, not days. The Shadow DOM approach eliminated all style conflict issues reported by users.
What Made the Timeline Possible
Three things: WXT handled the boilerplate, the adapter pattern let me build the architecture once and add sites incrementally, and Shadow DOM eliminated the need for debugging CSS conflicts. When you pick the right abstractions, shipping fast doesn’t mean shipping messy.