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

decentralised-db

v0.7.1

Published

Offline-first, P2P database with zero-knowledge encryption

Readme

DecentralisedDB

DecentralisedDB is a local-first encrypted database with optional cloud sync, realtime collaboration, and integrated AI routing. The core product boundary is simple:

  • private data stays local unless the app explicitly enables cloud sync
  • identities are based on a passphrase and a recovery phrase
  • collaboration and cloud features are opt-in
  • AI is attached as a provider layer, not the storage model

Production development currently uses this private source-of-truth; public releases are generated through the allowlisted open-source export so production ops, secrets, evidence, and Git history stay private. The current public source export is published at https://github.com/kevinseabourne/decentralised-db.

Current Product Surface

Supported authentication model

The supported user authentication and recovery model is:

  • createIdentity(passphrase)
  • loadIdentity(passphrase)
  • recoverIdentity(recoveryPhrase, newPassphrase)

Passkeys are not part of the supported product surface.

For Expo or React Native auth/session flows, use the dedicated auth client export:

  • decentralised-db/auth/expo-auth-session

For native-facing local-first database clients, use the runtime-backed entrypoints:

  • decentralised-db/expo
  • decentralised-db/desktop

Supported sync model

  • local-first writes through IndexedDB
  • optional encrypted cloud sync through the Cloudflare Worker API
  • optional realtime collaboration when cloud sync is enabled
  • authenticated media reads; anonymous/public media delivery is not part of the reviewed contract

Browser auth/session state should stay in IndexedDB-backed storage. The reviewed SDK path does not require localStorage for auth/session persistence.

The current SDK passphrase KDF for local unlock is Argon2id for newly created identities. Legacy PBKDF2-wrapped local keys remain readable so existing users can still unlock older accounts and migrate forward safely.

High-sensitivity deployment hardening

For sensitive deployments, the reviewed local auth/config path now supports external secret-manager supplied sealing keys:

  • JWST_AUTH_SESSION_SEALING_KEY_B64 injects the 32-byte base64 session seal key for jwst-auth
  • JWST_AUTH_REQUIRE_EXTERNAL_SESSION_SEALING_KEY=true makes jwst-auth fail closed if that key is not supplied
  • JWST_CLOUD_CONFIG_KEY_B64 injects the 32-byte base64 config seal key for jwst-cloud
  • JWST_CLOUD_REQUIRE_EXTERNAL_CONFIG_KEY=true makes jwst-cloud fail closed if that key is not supplied
  • when ENVIRONMENT=production or NODE_ENV=production, jwst-auth now requires an external session sealing key by default unless JWST_AUTH_ALLOW_LOCAL_SESSION_SEALING_KEY_IN_PRODUCTION=true is set explicitly
  • when ENVIRONMENT=production or NODE_ENV=production, jwst-cloud now requires an external config sealing key by default unless JWST_CLOUD_ALLOW_LOCAL_CONFIG_KEY_IN_PRODUCTION=true is set explicitly

This is an external-key path, not OS keychain / HSM integration.

The reviewed lookup-table path that removes legacy ALLOW FILTERING from cloud identity and owner reads also requires the runtime lookup schema in:

  • libs/jwst-cloud/scripts/create_runtime_lookup_tables.cql

Current AI runtime

The current reviewed runtime topology is:

  • default lane: deepinfra_qwen with Qwen/Qwen3.5-35B-A3B
  • supported lane: chutes_glm with zai-org/GLM-5.1-TEE

For sensitive deployments, the worker now keeps AI model selection fail-closed by default:

  • apps can discover the configured lanes through GET /api/ai/providers and let users choose among them explicitly
  • clients can use only the configured provider/model lanes unless operators explicitly allow additional model overrides
  • in multi-lane deployments, additional model overrides must be allowlisted per lane with AI_CHAT_PRIMARY_ALLOWED_MODEL_OVERRIDES, AI_CHAT_SECONDARY_ALLOWED_MODEL_OVERRIDES, or AI_CHAT_CHUTES_KIMI_ALLOWED_MODEL_OVERRIDES
  • legacy global model override env vars are honored only for single-lane deployments to avoid cross-provider routing surprises
  • Chutes Kimi can be enabled as an approved opt-in lane with AI_CHAT_CHUTES_KIMI_MODEL / AI_RUNTIME_CHUTES_KIMI_MODEL
  • if you need the thinking variant instead of the default K2.6 lane, set the Chutes Kimi model env var to the approved upstream model slug you want reviewed
  • the worker does not automatically fail over across providers during chat requests; if the selected lane is unavailable, the request fails closed on that lane
  • the upstream user field is pinned to the authenticated session subject by default; client-side overrides require explicit operator opt-in

Current notification layer

The Cloudflare Worker exposes a reviewed internal notification route for email delivery:

  • POST /internal/email/send

That route is intended for internal services and operator-controlled notification flows. It is not part of end-user auth.

Installation

pnpm install

SDK Quick Start

Local-only usage

import { DecentralizedDB } from 'decentralised-db';

const db = new DecentralizedDB({
  name: 'my-app',
  encryption: true,
  cloudSync: false,
});

await db.connect();

const identity = await db.createIdentity('your-long-passphrase');
// Present identity.recoveryPhrase once in a secure UI and require the user to
// store it offline. Do not log it or send it to analytics.

await db.create('notes', {
  title: 'Hello',
  body: 'Private local data',
});

const notes = await db.find('notes');
console.log(notes);

Local-first with cloud sync

import { DecentralizedDB } from 'decentralised-db';

const db = new DecentralizedDB({
  name: 'my-app',
  encryption: true,
  cloudSync: true,
  cloudEndpoint: 'https://api.decentralised-db.com',
});

await db.connect();

const session = await db.loadIdentity('your-passphrase');

await db.create('projects', {
  name: 'Launch',
  status: 'go',
});

db.subscribe('projects', (doc) => {
  console.log('Realtime change', doc);
});

Recovery flow

import { DecentralizedDB } from 'decentralised-db';

const db = new DecentralizedDB({
  name: 'my-app',
  encryption: true,
  cloudSync: true,
  cloudEndpoint: 'https://api.decentralised-db.com',
});

await db.connect();

await db.recoverIdentity(
  'your 24 word recovery phrase goes here',
  'your-new-passphrase',
);

Expo auth/session usage

import * as SecureStore from 'expo-secure-store';
import * as Crypto from 'expo-crypto';
import { createExpoAuthSessionClient } from 'decentralised-db/expo';

const auth = createExpoAuthSessionClient({
  secureStore: SecureStore,
  cryptoModule: Crypto,
  name: 'my-app',
  cloudEndpoint: 'https://api.decentralised-db.com',
});

await auth.connect();
const user = await auth.createIdentity('correct horse battery staple galaxy lantern');
const session = await auth.loadIdentity('correct horse battery staple galaxy lantern', user.id);

Expo local-first database usage

import * as SecureStore from 'expo-secure-store';
import * as SQLite from 'expo-sqlite';
import * as Crypto from 'expo-crypto';
import { createExpoDatabaseAsync } from 'decentralised-db/expo';

const db = await createExpoDatabaseAsync({
  name: 'my-app',
  encryption: true,
  cloudSync: true,
  cloudEndpoint: 'https://api.decentralised-db.com',
  sqliteModule: SQLite,
  secureStore: SecureStore,
  cryptoModule: Crypto,
});

await db.connect();
await db.loadIdentity('correct horse battery staple galaxy lantern');
await db.create('notes', { title: 'Hello from Expo' });
await db.uploadFile({
  uri: 'file:///data/user/0/app/cache/photo.jpg',
  name: 'photo.jpg',
  type: 'image/jpeg',
});

const accounts = await db.accounts.listAccounts();

Desktop local-first database usage

import keytar from 'keytar';
import { DatabaseSync } from 'node:sqlite';
import {
  DesktopDatabase,
  createDesktopCredentialStoreAdapter,
  createDesktopSqliteRuntime,
  createNodeSqliteSyncDriver,
} from 'decentralised-db/desktop';

const runtime = createDesktopSqliteRuntime({
  database: createNodeSqliteSyncDriver(new DatabaseSync('decentralised-db.sqlite')),
  secretStorage: createDesktopCredentialStoreAdapter(keytar, {
    service: 'decentralised-db',
    accountPrefix: 'desktop:',
  }),
});

const db = new DesktopDatabase({
  name: 'desktop-app',
  encryption: true,
  cloudSync: true,
  cloudEndpoint: 'https://api.decentralised-db.com',
  runtime,
  isOnline: () => true,
});

await db.connect();
await db.loadIdentity('correct horse battery staple galaxy lantern');
await db.create('documents', { title: 'Desktop local-first record' });
const accounts = await db.accounts.listAccounts();

Account Management

The current account-switching model is intentionally conservative:

  • account switching requires the account passphrase
  • deletion risk is surfaced before local account deletion
  • recovery depends on the recovery phrase, not biometric credentials

Repo Structure

  • /client-sdk — TypeScript SDK and browser-facing local/cloud logic
  • /cloudflare-workers — public API, sync, AI, and notification runtime
  • /libs/jwst-* — Rust core, auth, storage, codec, and related infrastructure
  • /scripts/ci — launch, signoff, audit, and CI automation
  • /scripts/ops — operational tooling and health/evidence helpers
  • /docs — current product and operator documentation

Key Docs

Read these first

Current operational and strategy docs

Supporting background docs

Development

Common commands:

pnpm install
pnpm run pack:sdk
pnpm run typecheck:launch
pnpm run typecheck:signaling
pnpm run test
bash scripts/enterprise-launch-gates.sh

Release and Safety Rules

  • never patch production directly
  • work through branches, merge requests, CI, canary, and rollback
  • do not commit secrets, backups, generated launch evidence, or local tool state
  • preserve the local-first and privacy boundary by default

GitLab

Canonical repository:

Issues:

License

MIT