Built with React, TypeScript, and Chrome Extension Manifest V3
⚠️ Source code is proprietary. This repo documents the architecture, my contributions, and technical decisions.
SERP Sonar is a Chrome extension that provides advanced Google Search Engine Results Page (SERP) analysis for digital marketers and SEO professionals. It extracts, visualizes, and benchmarks SERP data - turning hours of manual competitive analysis into seconds.
Users install the extension, search on Google, and instantly see analysis overlays on every search result: ranking position, rich snippet type, competitive metrics, and visual data breakdowns - all rendered directly on the SERP page.
Live SERP analysis toolbar - real-time scan progress and page-level SEO metrics, rendered directly on the Google results page.

Inline result annotations - schema type and title/meta rewrite flags tagged on each organic result.

SERP & keyword summary report - scan coverage, search term, and keyword targeting stats.

Keyword & word count visualizations - charts for in-title keyword distribution and word count by rank.

SERP & keyword detail report - page-by-page TF*IDF, keyword saturation, and exact keyword occurrence.

SERP title delta report - which page titles and descriptions Google rewrote for display.

Frontend Engineer (May 2022 – December 2024, Remote)
I independently designed and developed this extension from concept to deployment.
- Solution architecture
- UI/UX implementation
- React development
- TypeScript development
- Browser Extension architecture
- Chrome API integration
- Content Script development
- Background Service Worker implementation
- Runtime messaging
- Performance optimization
- Testing and debugging
- Chrome Web Store publishing
- React
- TypeScript
- HTML5
- CSS3
- Chrome Extension Manifest V3
- Chrome Extension APIs
- Content Scripts
- Background Service Workers
- Runtime Messaging
- Chrome Storage API
- Tabs API
- npm
- Git
- GitHub
| Layer | Technology |
|---|---|
| UI (Content Script) | React 18, TypeScript, TailwindCSS |
| Content Scripts | Vanilla JavaScript/TypeScript, DOM APIs |
| Background | Manifest V3 Service Worker |
| State Management | Redux, chrome.storage.session, chrome.storage.local |
| Data Visualization | Interactive charts and data overlays |
| Backend Integration | Firebase (Firestore, Auth), REST APIs, OpenAI |
| Build Tools | Webpack |
| Target Browsers | Chrome (Manifest V3) |
- Developed using Chrome Manifest V3
- Modular browser extension architecture
- Built reusable React components
- Content Script integration
- Background Service Worker implementation
- Runtime messaging between extension components
- Browser storage synchronization
- Optimized extension performance
- Clean and maintainable codebase
Problem: The SERP parser was processing the entire Google results page synchronously on page load. On complex SERPs with 100+ elements (rich snippets, knowledge panels, People Also Ask boxes, 50+ organic results), this blocked the main thread for 4-8 seconds, freezing the page completely.
Diagnosis: Chrome DevTools Performance tab showed a single enormous scripting task blocking the main thread. Timing markers revealed data extraction was the bottleneck at 2,800ms - caused by getComputedStyle() and getBoundingClientRect() calls triggering forced reflows inside a loop.
Solution:
- Restructured the parser into async chunks of 10 results, processed via
requestIdleCallback()so the browser stays responsive between batches - Batched all DOM reads (measurements) before DOM writes (badge rendering) to eliminate layout thrashing
- Replaced full DOM tree walking with targeted CSS selectors + data attribute flags to skip already-processed elements
Result: Processing time dropped from ~4,900ms to ~2,400ms. The longest individual main-thread block went from 4-8 seconds to under 50ms. Users could scroll and interact with the page immediately while analysis badges appeared progressively.
Problem: Excessive memory use from redundant DOM queries, plus a Manifest V3 service worker that wasn't managing state across its wake/sleep lifecycle.
Solution: Cached CSS selector results across the parsing pipeline, eliminated detached DOM node references blocking garbage collection, and moved runtime state into chrome.storage.session so it survives service worker restarts instead of living in memory.
Result: Chrome DevTools Memory snapshots confirmed a clear reduction in heap size and detached DOM nodes - memory usage dropped by approximately 20%.
This project strengthened my experience in:
- Browser Extension Development
- Chrome Manifest V3
- React
- TypeScript
- Browser Messaging
- Chrome APIs
- DOM Manipulation
- Extension Performance Optimization
- Scalable Frontend Architecture
