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 🙏

© 2025 – Pkg Stats / Ryan Hefner

cors-unlocker

v0.1.0

Published

Lightweight npm package for seamless CORS management through the CORS Unlocker browser extension. Perfect for API testing and cross-origin development.

Readme

cors-unlocker

A lightweight npm package for seamlessly managing Cross-Origin Resource Sharing (CORS) settings through the CORS Unlocker browser extension. Perfect for API testing, development, and cross-origin communication.

npm version TypeScript Gzipped Size

🚀 Quick Start

Installation

# Using npm
npm install cors-unlocker

# Using yarn  
yarn add cors-unlocker

# Using pnpm
pnpm add cors-unlocker

Basic Usage

import appCors from 'cors-unlocker';

// Check if extension is installed
const isInstalled = await appCors.isExtInstalled();

// Enable CORS (will prompt user for confirmation if needed)
const status = await appCors.enable({
  credentials: true,
  reason: 'Testing cross-origin API requests'
});

console.log('CORS enabled:', status.enabled, 'Credentials:', status.credentials);

🔧 How it Works

This package communicates with the CORS Unlocker browser extension through a secure iframe bridge. When CORS is enabled, the extension intelligently modifies HTTP responses by adding necessary Access-Control-Allow-Origin headers, enabling cross-origin requests without server-side changes.

Key Features

  • 🛡️ Secure Communication: Uses iframe messaging for safe extension interaction
  • Lightweight: Only 1.7KB gzipped - minimal impact on your application
  • 🎯 Smart Defaults: Automatically reads extension configuration for credentials
  • 🚫 No Timeouts: User confirmation dialogs have no artificial time limits
  • 📘 TypeScript Ready: Full type definitions included
  • 🔄 Reliable: Handles race conditions and communication errors gracefully

📚 API Reference

Extension Detection

isExtInstalled(): Promise<boolean>

Checks if the CORS Unlocker extension is available in the browser.

try {
  const isInstalled = await appCors.isExtInstalled();
  if (!isInstalled) {
    console.log('Please install the CORS Unlocker extension');
    appCors.openStorePage(); // Opens extension store
  }
} catch (error) {
  console.error('Extension check failed:', error.message);
}

Returns: Promise<boolean>
Throws: AppCorsError for communication failures


CORS Status Management

isEnabled(): Promise<{ enabled: boolean, credentials: boolean }>

Retrieves the current CORS status for the active page.

try {
  const status = await appCors.isEnabled();
  console.log('CORS Status:', status);
  // Returns: { enabled: boolean, credentials: boolean }
} catch (error) {
  console.error('Failed to get CORS status:', error.message);
}

Returns: Promise<{ enabled: boolean, credentials: boolean }>
Throws: AppCorsError for various error conditions


Enable CORS

enable(options?: IEnableOptions): Promise<{ enabled: boolean, credentials: boolean }>

Activates CORS for the current page. May require user confirmation and has no timeout limit to ensure reliable operation.

interface IEnableOptions {
  credentials?: boolean; // Use extension default if not specified
  reason?: string;       // Message shown to user during confirmation
}

Examples:

// Use extension's default credentials setting
const status = await appCors.enable();

// Enable with explicit credentials
const authStatus = await appCors.enable({ 
  credentials: true,
  reason: 'Testing authenticated API endpoints'
});

// Enable without credentials
const basicStatus = await appCors.enable({ 
  credentials: false,
  reason: 'Public API testing'
});

console.log('CORS enabled:', authStatus.enabled);
console.log('Credentials allowed:', authStatus.credentials);

Parameters:

  • credentials (optional): Enable credential-based requests. If not specified, uses the extension's default setting
  • reason (optional): Description shown to user during confirmation dialog

Returns: Promise<{ enabled: boolean, credentials: boolean }> - The resulting CORS status
Throws: AppCorsError for various error conditions including user cancellation

Note: This method may require user confirmation and has no timeout limit to avoid race conditions. The operation completes when the user responds or a natural system timeout occurs.


Disable CORS

disable(): Promise<void>

Safely disables CORS for the current page.

try {
  await appCors.disable();
  console.log('CORS disabled successfully');
} catch (error) {
  console.error('Failed to disable CORS:', error.message);
}

Returns: Promise<void>
Throws: AppCorsError for various error conditions


Extension Management

openExtOptions(): Promise<void>

Opens the extension's options/settings page.

try {
  await appCors.openExtOptions();
} catch (error) {
  console.error('Failed to open options:', error.message);
}

openStorePage(): void

Opens the browser's extension store page for CORS Unlocker installation.

// Redirect user to install the extension
appCors.openStorePage();

🎯 Practical Examples

Basic API Testing

import appCors from 'cors-unlocker';

async function testAPI() {
  try {
    // Check if extension is available
    if (!(await appCors.isExtInstalled())) {
      console.log('Extension not found, redirecting to store...');
      appCors.openStorePage();
      return;
    }

    // Enable CORS for testing
    await appCors.enable({ 
      reason: 'Testing third-party API integration' 
    });

    // Now you can make cross-origin requests
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log('API Response:', data);

    // Cleanup: disable CORS when done
    await appCors.disable();
  } catch (error) {
    console.error('API test failed:', error.message);
  }
}

Authenticated Requests

async function testAuthenticatedAPI() {
  try {
    // Enable CORS with credentials support
    const status = await appCors.enable({ 
      credentials: true,
      reason: 'Testing authenticated endpoints with cookies/headers'
    });

    if (status.credentials) {
      // Make authenticated cross-origin request
      const response = await fetch('https://api.example.com/user/profile', {
        credentials: 'include',
        headers: {
          'Authorization': 'Bearer your-token-here'
        }
      });
      
      const userData = await response.json();
      console.log('User data:', userData);
    }
  } catch (error) {
    console.error('Authenticated request failed:', error.message);
  }
}

React Hook Integration

import { useState, useEffect } from 'react';
import appCors from 'cors-unlocker';

function useCORS() {
  const [isInstalled, setIsInstalled] = useState(false);
  const [corsStatus, setCorsStatus] = useState({ enabled: false, credentials: false });
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function checkStatus() {
      try {
        const installed = await appCors.isExtInstalled();
        setIsInstalled(installed);
        
        if (installed) {
          const status = await appCors.isEnabled();
          setCorsStatus(status);
        }
      } catch (error) {
        console.error('Failed to check CORS status:', error);
      } finally {
        setLoading(false);
      }
    }
    
    checkStatus();
  }, []);

  const toggleCORS = async () => {
    try {
      if (corsStatus.enabled) {
        await appCors.disable();
        setCorsStatus({ enabled: false, credentials: false });
      } else {
        const newStatus = await appCors.enable({
          reason: 'Enable CORS for API testing'
        });
        setCorsStatus(newStatus);
      }
    } catch (error) {
      console.error('Failed to toggle CORS:', error);
    }
  };

  return { isInstalled, corsStatus, loading, toggleCORS };
}

⚠️ Error Handling

All async methods throw AppCorsError when operations fail. The error object provides detailed information for both debugging and user-friendly error handling.

Error Object Structure

class AppCorsError extends Error {
  readonly type: CorsErrorType;
  readonly message: string;
}

Error Types Reference

| Error Type | Description | Common Causes | |------------|-------------|---------------| | not-installed | Extension is not installed or not responding | User needs to install the CORS Unlocker extension | | user-cancel | User canceled the operation | User clicked "Cancel" in confirmation dialog | | forbidden-origin | Origin is not allowed to use the extension | Website is on extension's blocklist | | rate-limit | Too many requests from this origin | Excessive API calls in short time | | unsupported-origin | Origin protocol is not supported | Only http/https protocols are allowed | | communication-failed | Failed to communicate with extension | Network issues or extension crash | | config-error | Extension configuration error | Missing or invalid extension settings | | invalid-origin | Origin format is invalid | Malformed URL or invalid domain | | inner-error | Internal extension error | Extension bug or unexpected state | | unknown-error | Unexpected error occurred | Fallback for unhandled errors |

Comprehensive Error Handling

import appCors, { AppCorsError } from 'cors-unlocker';

async function robustCORSHandling() {
  try {
    // Attempt to enable CORS
    const status = await appCors.enable({ 
      credentials: true,
      reason: 'Testing cross-origin API integration'
    });
    
    console.log('✅ CORS enabled successfully:', status);
    return status;
    
  } catch (error) {
    if (error instanceof AppCorsError) {
      // Handle specific CORS-related errors
      switch (error.type) {
        case 'not-installed':
          console.log('📦 Extension not found. Redirecting to installation...');
          appCors.openStorePage();
          break;
          
        case 'user-cancel':
          console.log('❌ User canceled the operation');
          // Maybe show a gentle reminder about CORS benefits
          break;
          
        case 'forbidden-origin':
          console.error('🚫 This website is not allowed to use CORS Unlocker');
          // Show alternative solutions or contact info
          break;
          
        case 'rate-limit':
          console.warn('⏳ Too many requests. Please wait a moment...');
          // Implement exponential backoff retry
          break;
          
        case 'unsupported-origin':
          console.error('🌐 CORS Unlocker only works on http/https websites');
          break;
          
        case 'communication-failed':
          console.error('📡 Communication failed. Extension may be disabled.');
          // Maybe retry or suggest extension troubleshooting
          break;
          
        default:
          console.error('❗ CORS operation failed:', error.message);
          console.error('Error type:', error.type);
      }
    } else {
      // Handle unexpected errors
      console.error('💥 Unexpected error:', error);
    }
    
    throw error; // Re-throw if you want calling code to handle it
  }
}

Graceful Degradation Pattern

async function makeRequestWithCORS(url: string) {
  let corsEnabled = false;
  
  try {
    // Try to enable CORS first
    if (await appCors.isExtInstalled()) {
      await appCors.enable({ reason: 'API request requires CORS' });
      corsEnabled = true;
    }
  } catch (error) {
    console.warn('CORS unavailable, falling back to alternative:', error.message);
  }
  
  try {
    // Make the actual request
    const response = await fetch(url, {
      credentials: corsEnabled ? 'include' : 'same-origin'
    });
    return await response.json();
  } catch (fetchError) {
    if (!corsEnabled) {
      throw new Error(`Request failed. CORS Unlocker extension might help. Original error: ${fetchError.message}`);
    }
    throw fetchError;
  } finally {
    // Cleanup: disable CORS when done
    if (corsEnabled) {
      try {
        await appCors.disable();
      } catch (error) {
        console.warn('Failed to disable CORS:', error.message);
      }
    }
  }
}

🔗 Related Resources

📄 License

MIT License


Made with ❤️ for developers who need simple CORS solutions