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

@nostr-dev-kit/cache-browser

v1.0.0

Published

Browser-optimized NDK cache adapter with automatic WASM/IndexedDB fallback

Readme

@nostr-dev-kit/cache-browser

Browser-optimized NDK cache adapter with automatic WASM/IndexedDB fallback.

Features

  • Automatic Fallback: Tries SQLite WASM first for optimal performance, automatically falls back to IndexedDB (via Dexie) if WASM is unavailable
  • iOS Lockdown Mode Compatible: Gracefully handles environments where WebAssembly is disabled
  • Performance Optimized: Remembers which adapter works in localStorage to skip failed attempts on subsequent loads
  • Zero Configuration: Works out of the box with sensible defaults
  • Transparent: Drop-in replacement for other NDK cache adapters

Why?

Some browsers and security modes (like iOS Lockdown Mode) disable WebAssembly for security reasons. The high-performance @nostr-dev-kit/cache-sqlite-wasm adapter relies on WASM and won't work in these environments.

This adapter automatically detects when WASM is unavailable and seamlessly falls back to @nostr-dev-kit/cache-dexie (IndexedDB-based), ensuring your app works everywhere while using the fastest option available.

Installation

npm install @nostr-dev-kit/cache-browser

Usage

Basic Setup

import NDKCacheBrowser from '@nostr-dev-kit/cache-browser';
import NDK from '@nostr-dev-kit/ndk';

const cacheAdapter = new NDKCacheBrowser({
  dbName: 'my-app',
  workerUrl: '/worker.js',      // Path to SQLite WASM worker
  wasmUrl: '/sql-wasm.wasm',    // Path to SQLite WASM binary
});

const ndk = new NDK({
  cacheAdapter,
  // ... other NDK options
});

// Initialize cache before connecting
await cacheAdapter.initializeAsync(ndk);
await ndk.connect();

SvelteKit Example

// src/lib/ndk.svelte.ts
import NDKCacheBrowser from '@nostr-dev-kit/cache-browser';
import { createNDK } from '@nostr-dev-kit/svelte';

const cacheAdapter = new NDKCacheBrowser({
  dbName: 'my-app',
  workerUrl: '/worker.js',
  wasmUrl: '/sql-wasm.wasm',
  debug: true
});

export const ndk = createNDK({
  cacheAdapter,
  // ... other options
});

export const cacheInitialized = cacheAdapter.initializeAsync();

Options

type NDKCacheBrowserOptions = {
  // Database name (default: 'ndk-cache')
  dbName?: string;

  // Path to SQLite WASM worker script (required for WASM)
  workerUrl?: string;

  // Path to SQLite WASM binary (required for WASM)
  wasmUrl?: string;

  // Enable debug logging (default: false)
  debug?: boolean;

  // Force a specific adapter - useful for testing
  // Skips auto-detection and localStorage persistence
  forceAdapter?: 'wasm' | 'dexie';
};

How It Works

  1. First Load:

    • Tries to initialize SQLite WASM adapter
    • If WASM fails (e.g., iOS Lockdown Mode), tries Dexie (IndexedDB)
    • Saves successful adapter type to localStorage
  2. Subsequent Loads:

    • Checks localStorage for previously successful adapter
    • Tries that adapter first to avoid unnecessary initialization attempts
    • Still falls back to the other adapter if the preferred one fails
  3. Degraded Mode:

    • If both adapters fail, operates without persistent cache
    • App continues to work, just without caching benefits

Checking Active Adapter

// Get the currently active adapter type
const adapterType = cacheAdapter.getAdapterType();
console.log('Using adapter:', adapterType); // 'wasm' | 'dexie' | 'none'

// Get the underlying adapter instance (advanced use)
const adapter = cacheAdapter.getAdapter();

Manual Control

import {
  clearPreferredAdapter,
  getPreferredAdapter,
  setPreferredAdapter
} from '@nostr-dev-kit/cache-browser';

// Check current preference
const preferred = getPreferredAdapter(); // 'wasm' | 'dexie' | null

// Clear preference (forces re-detection on next load)
clearPreferredAdapter();

// Manually set preference (not recommended - let auto-detection handle it)
setPreferredAdapter('dexie');

Forcing an Adapter (Testing)

// Force WASM adapter only (fail if unavailable)
const wasmOnly = new NDKCacheBrowser({
  dbName: 'test',
  workerUrl: '/worker.js',
  wasmUrl: '/sql-wasm.wasm',
  forceAdapter: 'wasm'
});

// Force Dexie adapter only
const dexieOnly = new NDKCacheBrowser({
  dbName: 'test',
  forceAdapter: 'dexie'
});

Debug Logging

Enable debug logging to see adapter selection and initialization:

const cacheAdapter = new NDKCacheBrowser({
  debug: true
});

Or set the DEBUG environment variable:

DEBUG=ndk:cache-browser* npm run dev

Migration from Other Adapters

From @nostr-dev-kit/cache-sqlite-wasm

- import NDKCacheSqliteWasm from '@nostr-dev-kit/cache-sqlite-wasm';
+ import NDKCacheBrowser from '@nostr-dev-kit/cache-browser';

- const cacheAdapter = new NDKCacheSqliteWasm({
+ const cacheAdapter = new NDKCacheBrowser({
    dbName: 'my-app',
    workerUrl: '/worker.js',
    wasmUrl: '/sql-wasm.wasm',
  });

From @nostr-dev-kit/cache-dexie

- import NDKCacheDexie from '@nostr-dev-kit/cache-dexie';
+ import NDKCacheBrowser from '@nostr-dev-kit/cache-browser';

- const cacheAdapter = new NDKCacheDexie({
+ const cacheAdapter = new NDKCacheBrowser({
    dbName: 'my-app',
+   workerUrl: '/worker.js',  // Optional - enables WASM upgrade
+   wasmUrl: '/sql-wasm.wasm',
  });

When to Use

  • ✅ Browser-based Nostr apps
  • ✅ Apps that need iOS Lockdown Mode support
  • ✅ Apps that want optimal performance everywhere
  • ✅ Progressive Web Apps (PWAs)

Don't use for:

  • ❌ Node.js applications (use @nostr-dev-kit/cache-sqlite instead)
  • ❌ Environments where you control the runtime and know WASM works

Performance

  • WASM mode: ~10x faster than IndexedDB for complex queries
  • Dexie mode: Reliable IndexedDB performance, works everywhere
  • localStorage overhead: < 1ms on subsequent loads

License

MIT