npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

web-insight-analyzer

v1.0.0

Published

Production-grade library for analyzing web performance, Web Vitals, network requests, and resource coverage

Readme

web-insight-analyzer

npm version License: MIT TypeScript

A production-grade TypeScript library for comprehensive web performance analysis. Analyze Web Vitals, track network requests, identify unused CSS/JavaScript, and extract resource details with a clean, type-safe API.

Features

  • 🎯 Web Vitals Metrics: LCP, CLS, INP, FCP measurement
  • 📊 Network Analysis: Track all resources during initial page load
  • 🎨 CSS Coverage: Detect unused CSS rules and calculate coverage percentage
  • ⚙️ JavaScript Coverage: Track unused JavaScript code
  • 🖼️ Image Analysis: Extract image details, responsiveness, and lazy-loading status
  • Critical Resources: Automatic identification of critical vs. non-critical resources
  • Intelligent Recommendations: Actionable performance improvement suggestions with code examples
  • 🔌 Browser Abstraction: Pluggable browser adapter (Playwright included)
  • 📝 CLI Tool: Ready-to-use command-line interface with colored output
  • 🚀 Performance: Single browser session, no duplicate page loads
  • 🛡️ Type-Safe: 100% TypeScript with strict mode, zero any types
  • Fully Tested: Comprehensive unit and integration tests (77+ tests)
  • 🔍 Dev Mode: Watch local development with real-time re-analysis on file changes
  • 📡 Live Overlay: Inject lightweight Web Vitals display directly in browser (<10KB)
  • ⚙️ Vite Plugin: Automatic analysis integration for Vite dev servers
  • 🔄 Dev/Prod Comparison: Compare metrics between local and production builds

Installation

npm install web-insight-analyzer

# or with yarn
yarn add web-insight-analyzer

# or with pnpm
pnpm add web-insight-analyzer

Browser Installation

The package includes Playwright for browser automation. Browser binaries are automatically installed during the postinstall phase. If you need to manually install them:

npx playwright install

This downloads Chromium, Firefox, and WebKit (~400MB). You can install specific browsers:

# Install only Chromium (minimal ~200MB)
npx playwright install chromium

# Install only Firefox
npx playwright install firefox

# Install only WebKit
npx playwright install webkit

Note: If you see Failed to launch browser error, run npx playwright install to download the browser binaries.

Quick Start

Programmatic API

import { analyzePage } from 'web-insight-analyzer';

const result = await analyzePage('https://example.com');

console.log('Web Vitals:', result.webVitals);
console.log('Total Resources:', result.resources.length);
console.log('Unused CSS:', result.unusedCss.unusedPercentage + '%');
console.log('Images:', result.images.length);

CLI Usage

# Basic analysis
npx web-insight-analyzer https://example.com

# Output as JSON
npx web-insight-analyzer https://example.com --json

# Custom viewport
npx web-insight-analyzer https://example.com --viewport=1920x1080

# Visible browser
npx web-insight-analyzer https://example.com --headless=false

# Custom timeout
npx web-insight-analyzer https://example.com --timeout=60000

# Inject live Web Vitals overlay
npx web-insight-analyzer https://example.com --overlay

# Wait for specific element before analyzing
npx web-insight-analyzer https://example.com --wait-selector=".app-loaded"

# Watch local development and re-analyze on changes
npx web-insight-analyzer dev http://localhost:3000

# Compare local vs production
npx web-insight-analyzer compare http://localhost:3000 https://example.com

# Get detailed command help
npx web-insight-analyzer help [command]

API Reference

analyzePage(url, options?)

Main entry point for analyzing a web page.

Parameters:

  • url: string - URL to analyze
  • options?: AnalyzeOptions - Optional configuration

Returns: Promise<AnalyzeResult>

Example:

const result = await analyzePage('https://example.com', {
  timeout: 30000,
  headless: true,
  viewportWidth: 1280,
  viewportHeight: 720,
  waitUntil: 'networkidle'
});

AnalyzeResult Type

interface AnalyzeResult {
  url: string;
  duration: number; // milliseconds
  webVitals: WebVitals;
  resources: Resource[];
  unusedCss: CssCoverageReport;
  unusedJs: JsCoverageReport;
  images: ImageResource[];
}

WebVitals Type

interface WebVitals {
  lcp: number;      // Largest Contentful Paint (ms)
  cls: number;      // Cumulative Layout Shift
  inp: number;      // Interaction to Next Paint (ms)
  fcp: number;      // First Contentful Paint (ms)
}

Resource Type

interface Resource {
  url: string;
  mimeType: string;
  size: number;
  type: ResourceType;  // 'script' | 'stylesheet' | 'image' | 'font' | etc
  critical: boolean;
  duration: number;    // download time in ms
  statusCode: number;
  used: boolean;
}

CssCoverageReport Type

interface CssCoverageReport {
  unusedPercentage: number;
  totalBytes: number;
  unusedBytes: number;
  unusedSelectors: string[];
  files: CssCoverageFile[];
}

JsCoverageReport Type

interface JsCoverageReport {
  unusedPercentage: number;
  totalBytes: number;
  unusedBytes: number;
  files: JsCoverageFile[];
}

ImageResource Type

interface ImageResource {
  url: string;
  width: number;
  height: number;
  size: number;
  mimeType: string;
  isResponsive: boolean;
  isLazy: boolean;
  loadTime: number;
}

AnalyzeOptions Type

interface AnalyzeOptions {
  timeout?: number;              // milliseconds (default: 30000)
  headless?: boolean;            // default: true
  viewportWidth?: number;        // default: 1280
  viewportHeight?: number;       // default: 720
  waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
  waitSelector?: string;         // CSS selector to wait for before analyzing
  userAgent?: string;
  headers?: Record<string, string>;
  injectOverlay?: boolean;       // Inject Web Vitals overlay (default: false)
  devMode?: boolean;             // Flag for future dev-specific features
}

New Development Options:

  • waitSelector - CSS selector to wait for (useful for SPAs and dynamic content)
  • injectOverlay - Enable live Web Vitals display in browser
  • devMode - Reserved for future dev-specific features

Architecture

The package follows clean architecture principles with dependency injection:

src/
├── core/
│   ├── analyzer.ts          # Main orchestrator
│   ├── metrics.ts           # Web Vitals collection
│   ├── coverage.ts          # CSS/JS coverage analysis
│   └── network.ts           # Network request tracking
├── adapters/
│   └── playwrightAdapter.ts # Playwright implementation
├── types/
│   └── index.ts             # Type definitions
├── utils/
│   └── helpers.ts           # Utility functions
├── cli/
│   └── index.ts             # CLI implementation
└── index.ts                 # Public API

Dependency Injection

The PageAnalyzer accepts a BrowserAdapter interface, allowing you to provide custom browser implementations:

import { PageAnalyzer } from 'web-insight-analyzer';
import { CustomBrowserAdapter } from './my-adapter';

const analyzer = new PageAnalyzer(new CustomBrowserAdapter());
const result = await analyzer.analyzePage('https://example.com');
await analyzer.close();

Advanced Usage

Custom Browser Implementation

Implement the BrowserAdapter interface for alternative browsers:

import { BrowserAdapter, AnalyzeResult, AnalyzeOptions } from 'web-insight-analyzer';

class CustomAdapter implements BrowserAdapter {
  async analyzePage(url: string, options?: AnalyzeOptions): Promise<AnalyzeResult> {
    // Your custom implementation
  }

  async close(): Promise<void> {
    // Cleanup
  }
}

Error Handling

import { analyzePage, AnalyzerError, ErrorCode } from 'web-insight-analyzer';

try {
  const result = await analyzePage('https://example.com');
} catch (error) {
  if (error instanceof AnalyzerError) {
    console.error(`Error: ${error.message}`);
    console.error(`Code: ${error.code}`);
    
    if (error.code === ErrorCode.INVALID_URL) {
      // Handle invalid URL
    } else if (error.code === ErrorCode.TIMEOUT) {
      // Handle timeout
    }
  }
}

Batch Analysis

import { PageAnalyzer } from 'web-insight-analyzer';
import { createPlaywrightAdapter } from 'web-insight-analyzer';

const adapter = createPlaywrightAdapter();
const analyzer = new PageAnalyzer(adapter);

const urls = [
  'https://example1.com',
  'https://example2.com',
  'https://example3.com'
];

try {
  const results = await Promise.all(
    urls.map(url => analyzer.analyzePage(url))
  );
  
  // Process results
  results.forEach(result => {
    console.log(`${result.url}: ${result.webVitals.lcp}ms LCP`);
  });
} finally {
  await analyzer.close();
}

Performance Recommendations

The library includes an intelligent recommendation engine that generates actionable suggestions based on analysis results:

import { analyzePage, RecommendationEngine } from 'web-insight-analyzer';

const result = await analyzePage('https://example.com');
const recommendations = RecommendationEngine.generateRecommendations(result);

// Recommendations are sorted by severity (critical → info) and impact score
recommendations.forEach(rec => {
  console.log(`[${rec.severity}] ${rec.title}`);
  console.log(`  Impact: ${rec.impact}/100`);
  console.log(`  Advice: ${rec.advice}`);
  console.log(`  Example: ${rec.example}`);
});

Recommendation Categories

  • Web Vitals Optimization: LCP, CLS, INP, FCP improvements
  • CSS Coverage: Unused CSS elimination strategies
  • JavaScript Optimization: Code splitting and lazy loading
  • Resource Management: Render-blocking and large resource handling
  • Image Optimization: Responsive images and lazy-loading

Severity Levels

  • critical - Immediate action required (e.g., LCP > 4s)
  • high - Should be addressed soon (e.g., unused CSS > 50%)
  • medium - Would improve performance (e.g., missing alt text)
  • low - Nice-to-have optimization
  • info - Informational guidance

CLI Output

The CLI automatically displays the top 5 recommendations with severity color-coding:

npx web-insight-analyzer https://example.com

Output includes:

  • Recommendation title and severity
  • Impact score (50-100)
  • Affected metrics (LCP, CLS, etc.)
  • Detailed advice and code examples

Performance Considerations

  1. Single Session: The library uses a single browser context per analyzer instance
  2. No Duplicate Loads: Each page is loaded only once
  3. Network Idle Detection: Supports waiting for networkidle event
  4. Timeout Handling: Configurable timeout with graceful degradation
  5. Resource Cleanup: Properly closes browser on completion

Development Features

Dev Mode - Watch and Re-analyze

Monitor your local development environment in real-time with automatic re-analysis on file changes:

# Watch local dev server and re-analyze on every change
npx web-insight-analyzer dev http://localhost:3000

# With custom viewport
npx web-insight-analyzer dev http://localhost:3000 --viewport=768x1024

# With extended timeout for slower builds
npx web-insight-analyzer dev http://localhost:5173 --timeout=60000

The dev mode:

  • Watches your current directory for file changes
  • Re-runs analysis whenever files are modified
  • Displays incremental results
  • Gracefully handles SIGINT (Ctrl+C)
  • Perfect for catching performance regressions during development

Live Web Vitals Overlay

Inject a lightweight, real-time Web Vitals display directly into your browser:

# Analyze with overlay injection
npx web-insight-analyzer https://example.com --overlay

# Programmatically
import { analyzePage, getOverlayScript } from 'web-insight-analyzer';

const result = await analyzePage('https://example.com', {
  injectOverlay: true,
  waitUntil: 'networkidle'
});

The overlay displays:

  • LCP (Largest Contentful Paint) - Target: < 2.5s
  • FCP (First Contentful Paint) - Target: < 1.8s
  • CLS (Cumulative Layout Shift) - Target: < 0.1
  • INP (Interaction to Next Paint) - Target: < 200ms

Status colors:

  • 🟢 Green: Good (within thresholds)
  • 🟡 Yellow: Warning (near threshold)
  • 🔴 Red: Poor (exceeds threshold)

The overlay is less than 10KB and includes:

  • Real-time metric updates via PerformanceObserver
  • Toggle button to hide/show
  • Fixed positioning in top-right corner
  • No impact on page performance

Dev/Prod Comparison

Compare performance metrics between your local development build and production:

# Compare local vs production
npx web-insight-analyzer compare http://localhost:3000 https://example.com

# Output as JSON for programmatic processing
npx web-insight-analyzer compare http://localhost:3000 https://example.com --json

The comparison shows:

  • Side-by-side Web Vitals metrics
  • Percentage changes (improvement/regression)
  • Resource count and size differences
  • CSS/JavaScript coverage comparison
  • Image resource analysis
  • Recommendation severity differences

Example output:

Performance Comparison Report
================================================================================

URLs:
  Development: http://localhost:3000
  Production:  https://example.com

Web Vitals:
  LCP:  2100ms (dev) → 1800ms (prod) 🟢 14.3% improvement
  FCP:  900ms (dev) → 850ms (prod) 🟢 5.6% improvement
  CLS:  0.05 (dev) → 0.03 (prod) 🟢 40% improvement
  INP:  150ms (dev) → 120ms (prod) 🟢 20% improvement

Resources:
  Total Count: 45 (dev) → 52 (prod)
  Total Size:  2.1 MB (dev) → 2.3 MB (prod)

CSS Coverage: 85% (dev) → 92% (prod)
JavaScript Coverage: 78% (dev) → 88% (prod)

Images: 12 (dev) → 15 (prod)

Programmatically:

import { analyzePage, calculateMetricsDiff, formatMetricsDiff } from 'web-insight-analyzer';

const devResult = await analyzePage('http://localhost:3000');
const prodResult = await analyzePage('https://example.com');

const diff = calculateMetricsDiff(devResult, prodResult);
const formatted = formatMetricsDiff(diff);

console.log(formatted);

Vite Plugin Integration

Automatically inject analysis capabilities into your Vite dev server:

// vite.config.ts
import { defineConfig } from 'vite';
import { webInsightPlugin } from 'web-insight-analyzer/vite';

export default defineConfig({
  plugins: [
    webInsightPlugin({
      enabled: true,
      overlay: true,
      autoAnalyze: false,  // Manual trigger only
      onAnalysis: (result) => {
        console.log('Analysis complete:', result.webVitals);
      }
    })
  ]
});

Plugin configuration:

  • enabled (boolean, default: true) - Enable/disable the plugin
  • overlay (boolean, default: true) - Inject overlay script
  • autoAnalyze (boolean, default: false) - Auto-analyze on load
  • onAnalysis (callback) - Hook for analysis results
  • port (number) - Custom analysis server port

The plugin:

  • Injects overlay script into HTML
  • Provides HMR support for full-reload triggers
  • Zero configuration for basic usage
  • All features opt-in, no performance degradation

Waiting Strategies

Control how long the analyzer waits for pages to fully load:

# Wait for network idle (default, safest option)
npx web-insight-analyzer https://example.com --wait-until=networkidle

# Wait for page load event
npx web-insight-analyzer https://example.com --wait-until=load

# Wait for specific element to appear
npx web-insight-analyzer https://example.com --wait-selector=".content-ready"

# Combination: wait until network idle OR selector appears
npx web-insight-analyzer https://example.com \
  --wait-until=networkidle \
  --wait-selector=".app-initialized"

Programmatically:

const result = await analyzePage('https://example.com', {
  waitUntil: 'networkidle',     // 'load', 'domcontentloaded', 'networkidle'
  waitSelector: '.page-ready',   // CSS selector to wait for
  timeout: 30000                 // Timeout in milliseconds
});

CLI Examples

# Analyze homepage
npx web-insight-analyzer https://github.com

# Get JSON output for scripting
npx web-insight-analyzer https://google.com --json | jq '.webVitals.lcp'

# Run with custom viewport (tablet size)
npx web-insight-analyzer https://example.com --viewport=768x1024

# Visible browser for debugging
npx web-insight-analyzer https://example.com --headless=false

# Extended timeout for slow pages
npx web-insight-analyzer https://slow-site.com --timeout=60000

# Dev workflow: analyze with overlay + wait for custom selector
npx web-insight-analyzer dev http://localhost:3000 --overlay --wait-selector=".app"

# Compare production performance
npx web-insight-analyzer compare http://localhost:3000 https://prod.example.com

# Help for specific command
npx web-insight-analyzer help dev

Testing

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Generate coverage report
npm run test:coverage

# Run specific test file
npm test -- helpers.test.ts

Building

# Build to dist/
npm run build

# Clean build
npm run clean

# Type checking
npm run type-check

# Linting
npm run lint

# Format code
npm run format

Requirements

  • Node.js >= 16.0.0
  • TypeScript 5.3+
  • Playwright (included as dependency)

Browser Support

Currently supports Chromium via Playwright. Other browsers can be supported through custom adapters.

Troubleshooting

Browser Launch Failed

Error: Failed to launch browser or Browser not found

Solution: Playwright browsers are not installed. Run:

npx playwright install

This automatically happens during npm install, but if you see this error, manually run the command above.

403 Forbidden / Access Denied

Error: statusCode: 403 in results with only document resource

Cause: Website is blocking Playwright browser due to bot detection (Cloudflare, WAF, etc.)

Solutions:

  1. Use custom User-Agent:

    npx web-insight-analyzer https://example.com --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
  2. Use visible browser for testing:

    npx web-insight-analyzer https://example.com --headless=false
  3. Try with extended timeout:

    npx web-insight-analyzer https://example.com --timeout=60000

Zero Metrics (LCP/FCP = 0ms)

Cause: Page didn't fully load before analysis completed

Solutions:

  1. Use networkidle wait strategy (default):

    npx web-insight-analyzer https://example.com --wait-until=networkidle
  2. Wait for specific element:

    npx web-insight-analyzer https://example.com --wait-selector=".main-content"
  3. Increase timeout:

    npx web-insight-analyzer https://example.com --timeout=60000

Port Already in Use

Error: When using dev mode, port is already in use

Solution: The dev mode doesn't use ports; if you see this, restart your dev server or check for other processes using that port.

Out of Memory

Error: JavaScript heap out of memory or similar

Cause: Analyzing very large pages or many URLs in parallel

Solutions:

  1. Increase Node.js memory:

    node --max-old-space-size=4096 dist/cli/index.js https://example.com
  2. Analyze URLs sequentially instead of in parallel

  3. Close other applications to free up memory

Error Codes

  • INVALID_URL - Malformed URL provided
  • TIMEOUT - Analysis exceeded timeout limit
  • BROWSER_ERROR - Browser initialization failed
  • PAGE_LOAD_FAILED - Unable to load the page
  • NETWORK_ERROR - Network request failed
  • CDP_ERROR - Chrome DevTools Protocol error

Performance Metrics Guide

Web Vitals Interpretation

| Metric | Good | Needs Improvement | Poor | |--------|------|------------------|------| | LCP | < 2.5s | 2.5s - 4s | > 4s | | CLS | < 0.1 | 0.1 - 0.25 | > 0.25 | | INP | < 200ms | 200-500ms | > 500ms | | FCP | < 1.8s | 1.8s - 3s | > 3s |

Resource Prioritization

The library categorizes resources as critical or non-critical:

Critical Resources:

  • Stylesheets (render-blocking)
  • Inline scripts
  • Early-loaded resources (< 100ms)

Non-Critical Resources:

  • Async scripts
  • Images
  • Late-loading resources

Limitations

  1. Coverage Analysis: Requires Chrome/Chromium. Provides best-effort analysis; exact coverage may vary
  2. Network Simulation: No built-in network throttling (use Playwright's network interception)
  3. SPAs: Designed for initial page load; SPA navigation tracking requires custom implementation
  4. JavaScript Execution: Only tracks usage during initial load and network idle

Contributing

Contributions are welcome! Please ensure:

  • TypeScript strict mode compliance
  • Zero any types
  • Full type coverage
  • All tests pass
  • Code formatted with Prettier

License

MIT License - see LICENSE file for details

Roadmap

  • [x] Dev mode with file watching
  • [x] Live Web Vitals overlay (<10KB)
  • [x] Dev vs production comparison
  • [x] Vite plugin integration
  • [x] Selector-based waiting strategy
  • [ ] Network throttling profiles
  • [ ] Lighthouse integration
  • [ ] SPA navigation tracking
  • [ ] Video/WebP performance metrics
  • [ ] Core Web Vitals v2 support
  • [ ] Firefox support
  • [ ] Safari support
  • [ ] Regression detection
  • [ ] CI/CD integration plugins

Support

For issues, questions, or feature requests, please open an issue on GitHub.


Made with ❤️ for web performance enthusiasts