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

webextension-db

v0.1.0

Published

Unified database API for web extensions across Chrome, Firefox, and Safari with SQLite and JSON storage providers

Readme

WebExtension DB

A unified database API for web extensions that works seamlessly across Chrome, Firefox, and Safari. This package provides a consistent interface for persistent data storage in browser extensions, automatically handling browser differences and selecting the best available storage backend.

Features

  • 🌐 Cross-browser compatibility - Works on Chrome, Firefox, and Safari
  • 🔄 Automatic provider selection - Chooses the best storage backend for each browser
  • 💾 Multiple storage options - IndexedDB, Chrome Storage, Browser Storage APIs
  • 📊 JSON and SQLite support - Flexible data storage options
  • 🛡️ Type-safe - Full TypeScript support with comprehensive type definitions
  • High performance - Optimized for extension environments
  • 🔧 Easy to use - Simple, consistent API across all browsers

Installation

npm install webextension-db

Quick Start

import { createDatabase } from 'webextension-db';

// Create a database with automatic provider selection
const db = await createDatabase({
  name: 'my-extension-db',
  provider: 'auto',  // Automatically choose the best provider
  version: 1
});

// Store data
await db.set('users', 'user1', {
  name: 'John Doe',
  email: '[email protected]',
  preferences: { theme: 'dark' }
});

// Retrieve data
const user = await db.get('users', 'user1');
console.log(user); // { name: 'John Doe', email: '[email protected]', ... }

// Check if data exists
const exists = await db.exists('users', 'user1');

// Delete data
await db.delete('users', 'user1');

// Clear entire table
await db.clear('users');

Browser Support

| Browser | Storage Backend | Status | |---------|----------------|---------| | Chrome | Chrome Storage API, IndexedDB | ✅ Supported | | Firefox | Browser Storage API, IndexedDB | ✅ Supported | | Safari | IndexedDB (preferred), Browser Storage API | ✅ Supported | | Edge | Chrome Storage API, IndexedDB | ✅ Supported |

API Reference

createDatabase(config)

Creates a new database instance.

const db = await createDatabase({
  name: 'my-db',           // Database name
  provider: 'auto',        // 'auto', 'json', 'sqlite'
  version: 1,              // Schema version
  backend: 'indexeddb',    // Optional: force specific backend
  options: {
    area: 'local',         // 'local', 'sync', 'managed'
    autoSave: true,        // Auto-save for JSON provider
    saveInterval: 5000     // Save interval in ms
  }
});

Database Methods

Basic Operations

// Store data
await db.set(table, key, value);

// Retrieve data
const value = await db.get(table, key);

// Check existence
const exists = await db.exists(table, key);

// Delete data
await db.delete(table, key);

// Clear table
await db.clear(table);

Batch Operations

// Batch multiple operations
await db.batch([
  { type: 'set', table: 'users', key: 'user1', value: userData1 },
  { type: 'set', table: 'users', key: 'user2', value: userData2 },
  { type: 'delete', table: 'temp', key: 'old-data' }
]);

Table Management

// List all tables
const tables = await db.listTables();

// Create table (for SQLite provider)
await db.createTable('users', schema);

// Drop table
await db.dropTable('users');

Transactions

// Execute operations in a transaction
await db.transaction('readwrite', async (tx) => {
  const user = await tx.get('users', 'user1');
  user.lastActive = Date.now();
  await tx.set('users', 'user1', user);
  await tx.set('activity', Date.now(), { userId: 'user1', action: 'login' });
});

Extension Manifest Setup

Chrome (Manifest V3)

{
  "manifest_version": 3,
  "permissions": [
    "storage",
    "unlimitedStorage"
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

Firefox (Manifest V2)

{
  "manifest_version": 2,
  "permissions": [
    "storage",
    "unlimitedStorage"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

Usage in Extensions

Background Script

import { createDatabase } from 'webextension-db';

let db;

// Initialize database
async function initDB() {
  db = await createDatabase({
    name: 'extension-data',
    provider: 'auto'
  });
}

// Handle messages from popup/content scripts
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  handleMessage(message).then(sendResponse);
  return true; // Async response
});

async function handleMessage(message) {
  const { action, table, key, value } = message;
  
  switch (action) {
    case 'get':
      return await db.get(table, key);
    case 'set':
      await db.set(table, key, value);
      return { success: true };
    // ... other operations
  }
}

Popup Script

// Send message to background script
async function getData(table, key) {
  return new Promise((resolve) => {
    chrome.runtime.sendMessage(
      { action: 'get', table, key },
      resolve
    );
  });
}

async function setData(table, key, value) {
  return new Promise((resolve) => {
    chrome.runtime.sendMessage(
      { action: 'set', table, key, value },
      resolve
    );
  });
}

// Usage
const user = await getData('users', 'current');
await setData('settings', 'theme', 'dark');

Storage Backends

Automatic Selection

By default, the package automatically selects the best storage backend:

  1. Chrome: Chrome Storage API (with unlimitedStorage) → IndexedDB
  2. Firefox: Browser Storage API → IndexedDB
  3. Safari: IndexedDB (preferred for large storage) → Browser Storage API (10MB limit)

Manual Selection

You can force a specific backend:

const db = await createDatabase({
  name: 'my-db',
  provider: 'json',
  backend: 'chrome-storage' // or 'browser-storage', 'indexeddb'
});

Error Handling

try {
  await db.set('users', 'user1', userData);
} catch (error) {
  if (error.code === 'STORAGE_QUOTA_ERROR') {
    // Handle storage quota exceeded
    console.log('Storage quota exceeded');
  } else if (error.code === 'CONNECTION_ERROR') {
    // Handle connection issues
    console.log('Database connection failed');
  }
}

Development

# Install dependencies
npm install

# Build the package
npm run build

# Build examples
npm run build:examples

# Build everything (package + examples)
npm run build:all

# Run tests
npm test

# Build and watch for changes
npm run dev

Examples

Check out the examples directory for complete working examples:

Contributing

Contributions are welcome!

License

MIT ©