Josh Estrada
Back to work
Personal · Chrome Extension · Solo Designer, Developer & Operator

A passive Chrome extension that monitors for console errors, failed requests, layout shifts, accessibility violations, and security gaps while you develop

Four isolated execution contexts

Chrome extensions are distributed systems. MAIN world, content script, service worker, and side panel each run in isolation, connected by nonce-authenticated message passing.

Privacy-first, zero network requests

All data stays in the browser during normal operation. Only Pro license validation hits the network — everything else is local.

Performance budget: <5ms

Content script adds less than 5ms per page interaction. Total build is under 180KB. At that budget, the extension has no perceptible impact on page load or interaction speed.

344 tests

260 unit + 84 integration, 100% pass rate

10 detectors

Across 5 categories: Console, Network, Performance, Accessibility, Security

180KB total

All 4 contexts, 10 detectors, and the Preact side panel in one bundle

System Architecture

Designing the detection engine

The extension operates across 4 browser execution contexts with passive detection, nonce-authenticated messaging, and zero network requests during normal use

Browser Runtime
MAIN world page JS
Content script isolated
Service worker background
Side panel Preact SPA
4 isolated execution contexts
nonce-authenticated messaging
monitors
Detection Engine
10 Detectors × 5 Categories
Console errors
Promise rejections
Failed fetch/XHR
Slow responses
Layout shifts
Deprecated APIs
Missing alt text
ARIA violations
Mixed content
Security headers
Privacy-First Constraints
0
network requests during operation
<5ms
per page interaction
180KB
total extension build
Message Architecture
MAIN content worker panel
nonce-authenticated relay · dedup · suppression
surfaces
Actionable Issues
Categorized by severity
Suppression patterns
AI-ready clipboard export
Real-time display in side panel
structured for AI agent paste
Component anatomy

Designing a developer tool that stays out of the way

HushBug detects 10 issue types across 5 categories. The hard part is giving developers full control without getting in their way.

HushBug Config tab showing 10 detectors across 5 categories with individual toggles and threshold controls
"How are detectors configured?"
CONFIG TAB
Individual toggles and thresholds per detector

Each detector has its own toggle and threshold slider, grouped into 5 categories (Console, Network, Performance, Security, DOM). Turn on what you care about, ignore the rest. FREE/PRO badges on each detector show what's available on upgrade without locking anything down.

Design trade-off 10 detectors in a flat list gets cluttered fast. Grouping by category with collapsible sections means you find your detector in 1-2 clicks instead of scrolling.
HushBug Issues tab showing detected performance and security issues with expanded detail view, stack traces, and action buttons
"How are issues surfaced?"
ISSUES TAB
Grouped by category, detail on expand

Issues are grouped by category and sorted by severity. Each card shows type, message, and timestamp. Click to expand for stack traces, request details, and action buttons. The list stays scannable even with dozens of issues because the detail is hidden until you ask for it.

Design trade-off Stack traces inline would make the list unreadable. Expandable cards let you triage fast (scan titles) then go deep (expand for traces). That's how debugging actually works: broad scan first, focused investigation second.
HushBug Export tab showing issue queue with AI-optimized markdown export, JSON, and CSV format options
"How do issues leave the extension?"
EXPORT TAB
Three formats for different workflows

Select issues from the queue and pick a format. AI-optimized Markdown is structured for Claude, Cursor, and similar tools. JSON is for pipelines. CSV is for spreadsheets. Each format is shaped for its destination, not just a raw dump of the same data.

Design trade-off A single "copy all" button is simpler, but pasting into an AI agent needs different structure than filing a Jira ticket. One extra choice saves reformatting on every export.