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

sidepanel-fallback

v1.0.0

Published

A lightweight fallback utility for Chrome Extensions to handle side panel conflicts. Provides browser-specific storage and display mode switching with a clean developer API.

Readme

SidepanelFallback

A lightweight fallback utility for Chrome Extensions to handle side panel conflicts. Provides browser-specific storage and display mode switching with a clean developer API.

npm version License: MIT Tests Node.js CI TypeScript

Features

  • 🚀 Automatic Fallback: Seamlessly switch between Chrome sidepanel and popup window
  • 🌐 Cross-Browser Support: Works with Chrome, Firefox, Safari, Edge, and more
  • 💾 Persistent Settings: Per-browser mode preferences with localStorage/Chrome Storage API
  • 🎛️ Embeddable Settings UI: Ready-to-use settings component
  • 🧪 Test Driven: 150+ test cases with 100% coverage using Jest and @t_wada TDD principles
  • 📦 Zero Dependencies: Lightweight and self-contained
  • 🔧 Developer Friendly: Clean API with TypeScript support
  • Modern Build: ES6+ modules with UMD fallback via Vite
  • 📏 Code Quality: ESLint + Prettier for consistent code style

Quick Start

npm install sidepanel-fallback
import { SidepanelFallback } from 'sidepanel-fallback';

// Initialize
const fallback = new SidepanelFallback();
await fallback.init();

// Open panel (auto-detects best method)
await fallback.openPanel('/panel.html');

// Add settings UI
const container = document.getElementById('settings');
await fallback.withSettingsUI(container);

Why SidepanelFallback?

Chrome Extensions with sidepanel functionality face several challenges:

  • Browser Compatibility: Sidepanel API is Chrome-specific
  • API Availability: Not all Chrome versions support sidepanel
  • User Preferences: Some users prefer popup windows
  • Fallback Complexity: Manual fallback implementation is error-prone

SidepanelFallback solves these issues with a unified API that automatically handles browser detection, fallback logic, and user preferences.

Browser Support

| Browser | Sidepanel | Popup | Auto Mode | | ----------- | --------- | ----- | --------- | | Chrome 114+ | ✅ | ✅ | sidepanel | | Edge 114+ | ✅ | ✅ | sidepanel | | Firefox | ❌ | ✅ | window | | Safari | ❌ | ✅ | window |

API Overview

Core Methods

// Initialize the library
await fallback.init();

// Open a panel
const result = await fallback.openPanel('/panel.html');

// Add settings UI to container
await fallback.withSettingsUI(document.getElementById('settings'));

// Get current configuration
const settings = fallback.getCurrentSettings();

Chrome Extension Convenience API

For Chrome Extensions, we provide simplified methods:

// Setup extension configuration
await fallback.setupExtension({
  sidepanelPath: 'sidepanel.html',
  popupPath: 'popup.html'
});

// Handle action clicks with automatic mode detection
const result = await fallback.handleActionClick();

// Toggle between sidepanel and popup modes
await fallback.toggleMode();

Configuration Options

const fallback = new SidepanelFallback({
  defaultMode: 'auto', // 'auto', 'sidepanel', 'window'
  userAgent: 'custom-ua' // Override browser detection
});

Examples

Chrome Extension

// background.js
import { SidepanelFallback } from 'sidepanel-fallback';

const fallback = new SidepanelFallback();

chrome.action.onClicked.addListener(async () => {
  await fallback.init();
  const result = await fallback.openPanel('sidepanel.html');

  if (result.success) {
    console.log(`Panel opened using ${result.method}`);
  }
});

Chrome Extension with Simplified API

// background.js - Simplified API for easier development
import { SidepanelFallback } from 'sidepanel-fallback';

const fallback = new SidepanelFallback({ defaultMode: 'auto' });

// One-time setup
await fallback.setupExtension({
  sidepanelPath: 'sidepanel.html',
  popupPath: 'popup.html'
});

// Automatic mode handling
chrome.action.onClicked.addListener(async () => {
  await fallback.handleActionClick();
});

Web Application

// app.js
import { SidepanelFallback } from 'sidepanel-fallback';

const fallback = new SidepanelFallback();
await fallback.init();

document.getElementById('open-btn').onclick = () => {
  fallback.openPanel('/dashboard.html');
};

Complete Example

A production-ready Chrome Extension example is available in examples/chrome-extension/ featuring:

  • Manifest V3 compatibility
  • Automatic sidepanel ↔ popup fallback
  • Settings UI with persistent preferences
  • Shared UI components
  • Performance monitoring
npm run build
# Load examples/chrome-extension/ in chrome://extensions/

Documentation

Requirements

  • Node.js: 18.18.0 or higher
  • npm: 8.0.0 or higher
  • Browser: Chrome 88+, Firefox 78+, Safari 14+, Edge 88+

Node.js Compatibility

Actively tested on Node.js 18.x (LTS), 20.x (LTS), and 22.x (Current).

Note: Some advanced test suites are disabled on Node.js 20/22 due to Jest compatibility issues. Core functionality remains fully supported.

Test Commands

npm test           # Run core tests
npm run test:full  # Run full test suite (Node.js 18 recommended)

Development

Setup

git clone https://github.com/touyou/sidepanel-fallback.git
cd sidepanel-fallback
npm install

Commands

npm test                    # Run tests
npm run test:coverage       # Run tests with coverage
npm run dev                 # Start development server
npm run build               # Build for production
npm run quality             # Run lint + format check
npm run quality:fix         # Fix lint + format issues

Test Coverage

  • 150+ test cases with 100% pass rate
  • Complete API coverage across all modules
  • Cross-browser compatibility testing
  • Integration & End-to-End testing
  • Performance benchmarking and memory leak detection

Architecture

Built as focused, testable modules:

src/
├── index.js              # Main API
├── browserInfo.js        # Browser detection
├── modeStorage.js        # Settings persistence
├── panelLauncher.js      # Panel opening logic
└── settingsUI.js         # Settings UI component

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Process

  1. Fork the repository
  2. Create a feature branch
  3. Write tests first (TDD approach)
  4. Implement the feature
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Support


Made with ❤️ by touyou