This guide explains how the NetSTAR browser extension works, how files interact, and how to develop on this project.
- Application Overview
- Architecture
- File Structure
- Component Architecture
- Data Flow
- Key Concepts
- Development Workflow
- Extension Lifecycle
- Adding New Features
NetSTAR is a Chrome extension (Manifest V3) that provides real-time security analysis for websites. The extension consists of two main parts:
- Popup Interface - A React-based UI that shows when users click the extension icon
- Background Service Worker - A JavaScript service worker that monitors tabs and performs security scans
- Real-time Security Scoring - Analyzes current website and displays safety score (0-100)
- Tab-Based Navigation - Home, Scan, Alerts, and Settings tabs
- Interactive Tour - Guided walkthrough for new users
- Theme Support - Light/dark mode toggle
- Dynamic Icons - Extension icon changes based on website security status
- React 19 - UI framework with modern hooks
- Vite 5 - Build tool and dev server with HMR
- @crxjs/vite-plugin - Enables hot module reloading for Chrome extensions
- Tailwind CSS 4 - Utility-first CSS framework
- Chrome Extension API (Manifest V3) - Extension functionality
- shadcn/ui - Accessible component library
- Lucide React - Icon library
┌─────────────────────────────────────────────────┐
│ Browser Tab (User's Website) │
└───────────────────┬─────────────────────────────┘
│
│ Chrome Extension API
│
┌───────────┴───────────┐
│ │
┌───────▼────────┐ ┌─────────▼──────────┐
│ Background.js │ │ Popup.jsx │
│ (Service │ │ (React UI) │
│ Worker) │ │ │
│ │ │ ┌───────────────┐ │
│ - Monitors │◄───┤ │ Tab Components│ │
│ tabs │ │ │ - HomeTab │ │
│ - Performs │ │ │ - ScanTab │ │
│ scans │ │ │ - AlertsTab │ │
│ - Updates icon │ │ │ - DetailsTab │ │
│ │ │ └───────────────┘ │
└────────────────┘ └────────────────────┘
src/
├── manifest.json # Extension configuration (permissions, icons, etc.)
├── index.html # HTML entry point for popup
├── popup.jsx # Main React component (renders entire popup)
├── background.js # Service worker (runs in background)
└── index.css # Global styles (Tailwind + custom theme)
popup.jsx (Root)
│
├── Header (Title, Theme Toggle, Settings Button)
│
├── Tab Navigation
│ ├── HomeTab
│ │ ├── Security Score Display
│ │ └── Security Indicators (expandable list)
│ │
│ ├── ScanTab
│ │ ├── URL Input
│ │ └── Recent Scans
│ │
│ ├── AlertsTab
│ │ └── Security Alert Cards
│ │
│ ├── DetailsTab (shown when indicator clicked)
│ │ ├── Indicator Details
│ │ └── Educational Content
│ │
│ └── SettingsTab
│ └── Settings Sections
│
└── Tour Component (overlay when active)
src/
├── components/
│ ├── tabs/ # Tab-specific components
│ │ ├── HomeTab.jsx
│ │ ├── ScanTab.jsx
│ │ ├── AlertsTab.jsx
│ │ ├── DetailsTab.jsx
│ │ └── SettingsTab.jsx
│ │
│ ├── ui/ # Reusable UI components (shadcn/ui)
│ │ ├── button.jsx
│ │ ├── badge.jsx
│ │ ├── input.jsx
│ │ └── ...
│ │
│ ├── Tour.jsx # Guided tour component
│ └── ThemeToggleIcon.jsx # Reusable theme icon
│
└── lib/ # Utility functions and data
├── constants.js # App-wide constants (indicators, scans)
├── educationalContent.js # Educational content for indicators
├── securityUtils.js # Security-related utilities
├── themeUtils.js # Theme styling utilities
└── utils.js # General utilities (cn helper)
Responsibilities:
- Manages application state (active tab, theme mode, tour state)
- Handles tab navigation
- Coordinates between tabs and tour
- Renders header and tab navigation
Key State:
- mode: "light" | "dark" // Theme mode
- activeTab: string // Current tab ID
- selectedIndicator: object | null // Selected security indicator
- isTourActive: boolean // Whether tour is running
- forceShowIndicators: boolean // Controls indicator expansion (for tour)Component Flow:
User clicks tab → setActiveTab() → Re-render → Show appropriate Tab component
User clicks indicator → onNavigate("details", data) → Show DetailsTab
User starts tour → setIsTourActive(true) → Tour component renders overlay
- Displays current website's security score
- Shows expandable list of security indicators
- Fetches current tab URL from background script
- Allows navigation to DetailsTab when indicator clicked
Data Flow:
1. Component mounts
2. Sends message to background.js: { action: 'getCurrentTab' }
3. Background responds with { url, securityData }
4. Component updates state with safety score and URL
5. Renders indicators from DEFAULT_INDICATOR_DATA (constants.js)
- Manual URL scanning interface
- Shows scanning animation
- Displays recent scans from constants
- Shows detailed information about a selected security indicator
- Displays educational content (from
lib/educationalContent.js) - Uses status utilities to determine colors and styling
- Displays high-priority security alerts
- Simple card-based layout
- Settings and preferences
- Access to guided tour
Purpose: Interactive guided walkthrough
How it works:
- Defines array of tour steps (each step has tab, title, description, highlightId, position)
- Manages current step index
- Auto-navigates to required tab for each step
- Highlights elements using CSS or spotlight overlay
- Calculates spotlight position for button highlights dynamically
Key Features:
- Auto-navigation between tabs
- Element highlighting (CSS shadow for regular elements, spotlight overlay for buttons)
- Step counter and progress bar
- Back/Next/Skip controls
Integration:
- Receives
currentTabprop to know which tab is active - Calls
onNavigate()to switch tabs as needed - Calls
onStepChange()to notify parent of step changes (for auto-expanding indicators)
Responsibilities:
- Monitors tab updates
- Performs security scans (currently simulated)
- Updates extension icon based on safety score
- Responds to messages from popup
- Manages extension storage
Key Functions:
- updateIcon(tabId, safetyScore) // Updates extension icon
- performSecurityScan(url) // Simulates security scanEvent Listeners:
chrome.runtime.onInstalled- Sets default icon on installchrome.tabs.onUpdated- Scans page when tab finishes loadingchrome.tabs.onActivated- Updates icon when user switches tabschrome.runtime.onMessage- Handles messages from popup
Icon Thresholds:
- Score >= 75: Safe (green icon)
- Score >= 60: Warning (yellow icon)
- Score < 60: Danger (red icon)Message API:
{ action: 'getCurrentTab' }→ Returns current tab URL and security data{ action: 'scanUrl', url: string }→ Performs scan and returns results
1. User clicks extension icon
└── Browser opens popup (index.html)
2. popup.jsx mounts
└── Sets initial state (mode: "light", activeTab: "home")
3. HomeTab renders
└── Sends message to background.js: { action: 'getCurrentTab' }
4. background.js receives message
├── Queries active tab: chrome.tabs.query()
├── Retrieves cached scan data from storage
└── Sends response: { url, securityData }
5. HomeTab receives response
├── Updates currentUrl state
├── Updates safetyScore state
└── Renders UI with data
6. User clicks a security indicator
└── Calls onNavigate("details", indicatorData)
7. popup.jsx handles navigation
├── Sets selectedIndicator state
├── Sets activeTab to "details"
└── DetailsTab renders with indicator data
8. DetailsTab displays
├── Gets educational content from educationalContent.js
├── Determines status using securityUtils.js
├── Gets styling using themeUtils.js
└── Renders detailed view
1. User navigates to a new website
└── Chrome fires chrome.tabs.onUpdated event
2. background.js receives event
├── Checks if tab.status === 'complete'
├── Calls performSecurityScan(tab.url)
└── Stores result in chrome.storage.local
3. performSecurityScan() runs
├── Generates/simulates safety score
└── Returns security data object
4. updateIcon() called with safety score
├── Determines icon state (safe/warning/danger)
└── Updates extension icon using chrome.action.setIcon()
5. User clicks extension icon
└── Popup retrieves cached scan data (as shown above)
The app uses a centralized theme system:
Implementation:
- Theme mode stored in
popup.jsxstate - Passed as
modeprop to all components - CSS uses Tailwind's dark mode variant (
.darkclass) - Theme utilities in
lib/themeUtils.js
Theme Helper:
import { themeValue } from '@/lib/themeUtils'
// Instead of: mode === "dark" ? "dark-class" : "light-class"
const className = themeValue(mode, "light-class", "dark-class")Custom Properties:
- Brand colors defined in
index.cssas CSS custom properties - Uses OKLCH color space for better color interpolation
- Separate light/dark mode color definitions
Status Levels:
- excellent (score >= 90)
- good (score >= 75)
- moderate (score >= 60)
- poor (score < 60)Utilities:
getStatusFromScore(score)- Converts score to statusgetColorClasses(status)- Returns color classes for statusgetStatusInfo(status)- Returns complete styling info
Usage:
const status = getStatusFromScore(safetyScore)
const colors = getColorClasses(status)
// Returns: { bg, text, gradient }Purpose: Centralized configuration for easy updates
Files:
-
lib/constants.js- App-wide constantsDEFAULT_INDICATOR_DATA- Security indicator definitionsDEFAULT_RECENT_SCANS- Demo scan history
-
lib/educationalContent.js- Educational content- Large object with explanations for each indicator type
- Exported as
EDUCATIONAL_CONTENTobject
Benefits:
- Easy to update indicator scores
- Single source of truth for data
- Maintainable content management
Tab Components:
- Receive
modeprop for theme - Receive callback props for navigation (
onNavigate,onBack) - Self-contained logic and state
- Minimal props (just what's needed)
Reusable Components:
ThemeToggleIcon- Theme-aware icon component- UI components in
components/ui/- shadcn/ui components
Utility Functions:
- Extract repeated logic to
lib/files - Pure functions when possible
- Clear naming and documentation
Key APIs Used:
-
chrome.action - Extension icon and popup
chrome.action.setIcon({ path: {...} })
-
chrome.tabs - Tab information
chrome.tabs.query({ active: true, currentWindow: true }) chrome.tabs.get(tabId)
-
chrome.storage.local - Data persistence
chrome.storage.local.set({ key: value }) chrome.storage.local.get(['key'])
-
chrome.runtime - Messaging
chrome.runtime.sendMessage({ action: '...' }) chrome.runtime.onMessage.addListener(...)
# Node.js 16+ required
node --version
# Install dependencies
npm install# Start dev server with hot reload
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview- Run
npm run dev(createsdist/folder) - Open
chrome://extensions/oredge://extensions/ - Enable "Developer mode" (top right)
- Click "Load unpacked"
- Select the
dist/folder
The @crxjs/vite-plugin enables HMR for extensions:
- Changes to React components automatically update
- No need to reload extension manually
- Background script changes require extension reload
Vite watches for changes in:
src/**/*.jsx,src/**/*.jssrc/**/*.csssrc/manifest.json
Changes trigger:
- Component re-render (UI files)
- Extension rebuild (manifest, background)
- User installs extension
chrome.runtime.onInstalledfires- Background script:
- Sets default icon
- Initializes storage with default values
- Logs installation
- User navigates to website
chrome.tabs.onUpdatedfires when page loads- Background script:
- Performs security scan
- Updates extension icon
- Caches scan result
- User switches to different tab
chrome.tabs.onActivatedfires- Background script:
- Checks for cached scan data
- Updates icon if cached, or performs new scan
- User clicks extension icon
- Browser opens popup (
index.html) - React app initializes (
popup.jsx) - Active tab requests data from background
- Background responds with cached or fresh data
- UI renders with security information
-
Create Tab Component
// src/components/tabs/NewTab.jsx export function NewTab({ mode, onNavigate }) { return <div>New Tab Content</div> }
-
Import in popup.jsx
import { NewTab } from "@/components/tabs/NewTab"
-
Add Tab Definition
const tabs = [ // ... existing tabs { id: "new", label: "New", icon: IconComponent } ]
-
Add Tab Rendering
{activeTab === "new" && <NewTab mode={mode} />}
-
Add to constants.js
export const DEFAULT_INDICATOR_DATA = [ // ... existing indicators { id: "new-metric", name: "New Metric", score: 85 } ]
-
Add Icon Mapping (if needed)
// In HomeTab.jsx const INDICATOR_ICONS = { // ... existing mappings "new-metric": NewIconComponent }
-
Add Educational Content
// In lib/educationalContent.js export const EDUCATIONAL_CONTENT = { // ... existing content "new-metric": [ { title: "...", description: "..." } ] }
- Update steps array in Tour.jsx
const steps = [ // ... existing steps { tab: "home", title: "New Feature", description: "Explanation...", highlightId: "element-id", // or null position: "bottom" } ]
-
Add to background.js
// New event listener chrome.someAPI.onEvent.addListener((data) => { // Handle event }) // New message handler chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'newAction') { // Handle action sendResponse({ result: '...' }) } })
-
Call from Popup
chrome.runtime.sendMessage( { action: 'newAction', data: {...} }, (response) => { // Handle response } )
- Use Tailwind classes - Prefer utility classes
- Theme-aware - Always support light/dark mode
className={mode === "dark" ? "dark-class" : "light-class"} // Or use themeValue helper className={themeValue(mode, "light", "dark")}
- Use brand colors - Use
brand-*classes for consistency - Responsive - Popup is fixed size (500px), but consider smaller screens
// In component
useEffect(() => {
chrome.runtime.sendMessage(
{ action: 'getCurrentTab' },
(response) => {
if (response?.url) {
setCurrentUrl(response.url)
}
if (response?.securityData) {
setSecurityData(response.securityData)
}
}
)
}, [])// Navigate to details
onNavigate("details", indicatorData)
// Navigate to tab
setActiveTab("scan")
// Go back
onBack() // Sets activeTab to "home"// Class names
className={`${mode === "dark" ? "bg-slate-900" : "bg-white"}`}
// Using theme helper
import { themeValue } from '@/lib/themeUtils'
className={themeValue(mode, "bg-white", "bg-slate-900")}import { getStatusFromScore, getColorClasses } from '@/lib/securityUtils'
const status = getStatusFromScore(score)
const colors = getColorClasses(status)
// Use colors
<div className={colors.bg}>
<Icon className={colors.text} />
</div>-
Popup DevTools
- Right-click extension icon → "Inspect popup"
- Standard React DevTools work
-
Background Script DevTools
- Go to
chrome://extensions/ - Find extension → Click "service worker" link
- Opens DevTools for background script
- Go to
-
View Storage
- In background DevTools → Application tab → Storage
- View
chrome.storage.localdata
Icon not updating:
- Check background.js console for errors
- Verify icon paths in
src/icons/exist - Ensure
chrome.action.setIconis called correctly
Popup not showing data:
- Check popup DevTools console for errors
- Verify message passing between popup and background
- Check that background script is running (service worker status)
Styles not applying:
- Ensure Tailwind is building correctly
- Check for class name typos
- Verify dark mode class is on root element
Tour highlighting not working:
- Check element IDs match
highlightIdin steps - Verify element exists when tour step renders
- Check console for JavaScript errors
extension-proto-1/
├── src/ # Source code
│ ├── manifest.json # Extension manifest
│ ├── index.html # Popup HTML
│ ├── popup.jsx # Root React component
│ ├── background.js # Service worker
│ ├── index.css # Global styles
│ │
│ ├── components/ # React components
│ │ ├── tabs/ # Tab views
│ │ ├── ui/ # Reusable UI components
│ │ ├── Tour.jsx # Guided tour
│ │ └── ThemeToggleIcon.jsx # Theme icon
│ │
│ ├── lib/ # Utilities and data
│ │ ├── constants.js # App constants
│ │ ├── educationalContent.js # Educational data
│ │ ├── securityUtils.js # Security helpers
│ │ ├── themeUtils.js # Theme helpers
│ │ └── utils.js # General utilities
│ │
│ └── icons/ # Extension icons
│
├── dist/ # Build output (generated)
├── docs/ # Documentation
├── vite.config.js # Vite configuration
├── package.json # Dependencies
└── README.md # Project overview
-
Read the Code
- Start with
popup.jsxto understand structure - Review
HomeTab.jsxfor data flow example - Check
background.jsfor extension API usage
- Start with
-
Run the Extension
- Follow setup instructions
- Load extension in browser
- Test each tab and feature
-
Explore Components
- Check
components/tabs/for tab implementations - Review
lib/for utility functions - Understand
Tour.jsxfor interactive features
- Check
-
Make Small Changes
- Update indicator scores in
constants.js - Modify styling in components
- Add new tour steps
- Update indicator scores in
-
Understand Data Flow
- Trace data from background → popup → components
- Understand message passing
- Review storage usage
If you encounter issues or have questions:
- Check this guide first
- Review code comments in relevant files
- Check browser console for errors
- Verify extension is properly loaded
- Review Chrome Extension API documentation
Happy coding! 🚀