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

bff-store

v0.1.1

Published

A jotai-based state management library with pluggable storage adapters

Readme

bff-store

A jotai-based state management library with pluggable storage adapters and built-in BFF (Backend for Frontend) for browser/Next.js environments.

Features

  • Configuration-driven: Define multiple states via array configuration
  • Pluggable storage: Use memory, JSONL files, MongoDB, or remote server
  • Auto-generated hooks: React hooks auto-generated from config
  • Loading states: Built-in loading state tracking
  • Debounced saves: Automatic debouncing for non-critical data
  • Built-in BFF: Embedded sidecar API server for browser/Next.js environments

Architecture

┌─────────────────────────────────────────────────────────┐
│                    Your Application                       │
│                   (Next.js/Browser)                      │
│                                                          │
│  useStore() ──► remoteStorage ──► localhost:3847        │
│                         │                                │
│                         ▼                                │
│              ┌─────────────────────┐                     │
│              │   BFF (Sidecar)     │                     │
│              │  bff-store │                     │
│              │                     │                     │
│              │  /storage/get/:key  │                     │
│              │  /storage/set/:key  │                     │
│              │  /storage/delete   │                     │
│              └──────────┬──────────┘                     │
│                         │                                │
│                         ▼                                │
│              ┌─────────────────────┐                     │
│              │   JSONL / MongoDB   │                     │
│              └─────────────────────┘                     │
└─────────────────────────────────────────────────────────┘

Installation

npm install bff-store
# or
pnpm add bff-store

Client Usage (Browser / Next.js)

BFF Server 会自动启动,客户端只需使用 remoteStorage() 并指定存储后端:

import { createStore, useStore, remoteStorage } from 'bff-store';

const config = [
  { key: 'theme', defaultValue: 'dark' },
  { key: 'characters', defaultValue: [] },
] as const;

// 使用 MongoDB 存储
const store = createStore('my-app', config, {
  storage: remoteStorage({
    backend: 'mongodb',
    mongoUrl: 'mongodb://user:pass@host:27017',
    mongoDb: 'myapp',
  }),
});

// 或使用 JSONL 存储
// const store = createStore('my-app', config, {
//   storage: remoteStorage({
//     backend: 'jsonl',
//     jsonlDir: '/tmp/my-app-data',
//   }),
// });

在 React 组件中使用

function App() {
  const { theme, setTheme, isLoading } = useStore(store);

  if (isLoading) return <div>Loading...</div>;

  return <input value={theme} onChange={e => setTheme(e.target.value)} />;
}

自定义 BFF 服务器地址

// 如果 BFF 运行在其他地址
const adapter = remoteStorage({ baseUrl: 'http://localhost:3847' });
const adapter = remoteStorage({ entityId: 'user-123' });  // 多租户支持

Memory Storage (不持久化)

适用于开发环境或不需要持久化的场景:

import { createStore, useStore, memoryStorage } from 'bff-store';

const store = createStore('my-app', config, {
  storage: memoryStorage(),  // 不走 BFF,数据仅存在内存
});

Advanced: 手动启动 BFF Server

大多数情况不需要手动启动 BFF,它会自动启动。如需手动控制:

import { startServer } from 'bff-store/server';

await startServer({
  port: 3847,
});

Node.js 直接使用 Storage Adapters

如果不通过 BFF,可以直接在 Node.js 中使用存储适配器:

import { createNodeStore, getDefaultStore } from 'bff-store';
import { jsonlStorage } from 'bff-store/jsonl';
import { mongodbStorage } from 'bff-store/mongodb';

// 使用 JSONL
const store = createNodeStore('entity-123', [
  { key: 'theme', defaultValue: 'dark' },
  { key: 'count', defaultValue: 0 },
], {
  storage: jsonlStorage({ dir: './sessions' }),
});

// 等待初始加载完成
await store.waitForLoad();

// 使用 jotai getDefaultStore() 读写
const jotai = getDefaultStore();
jotai.set(store.atoms.theme, 'light');   // 自动 debounce 持久化
console.log(jotai.get(store.atoms.count));

// 或使用 MongoDB
const store2 = createNodeStore('entity-456', [
  { key: 'data', defaultValue: null },
], {
  storage: await mongodbStorage({
    url: 'mongodb://localhost:27017',
    database: 'myapp',
  }),
});

环境检测

import { isNode, isBrowser } from 'bff-store';

if (isNode()) {
  // Node.js 环境
}

if (isBrowser()) {
  // 浏览器环境
}

API Endpoints (BFF Server)

| Method | Endpoint | Body | Description | |--------|----------|------|-------------| | GET | /storage/get/:key?entityId=x | - | Get value by key | | POST | /storage/set/:key?entityId=x | { value } | Set value | | DELETE | /storage/delete/:key?entityId=x | - | Delete key | | POST | /storage/batch-get?entityId=x | { keys: [] } | Batch get | | POST | /storage/batch-set?entityId=x | { entries: {} } | Batch set | | GET | /health | - | Health check |

API Reference

createStore(entityId, config, options)

Creates a store with multiple persisted atoms.

  • entityId: Unique identifier for this store instance
  • config: Array of atom configurations
  • options.storage: Storage adapter (required)
  • options.debounceMs: Debounce delay in ms (default: 800)

useStore(store)

React hook to use the store in components.

Returns: { ...data, ...setters, isLoading }

Setter names are derived by capitalizing the config key:

  • themesetTheme
  • userNamesetUserName

remoteStorage(options?)

Creates a remote storage adapter for connecting to the BFF server.

// 基本用法 - BFF 使用默认存储后端
const adapter = remoteStorage();

// 指定使用 MongoDB
const adapter = remoteStorage({
  backend: 'mongodb',
  mongoUrl: 'mongodb://user:pass@host:27017',
  mongoDb: 'myapp',
});

// 指定使用 JSONL
const adapter = remoteStorage({
  backend: 'jsonl',
  jsonlDir: '/tmp/my-app-data',
});
  • options.baseUrl: BFF server URL (default: http://localhost:3847)
  • options.entityId: Default entityId for all requests
  • options.backend: Storage backend type 'mongodb' or 'jsonl'
  • options.mongoUrl: MongoDB connection URL (required if backend is mongodb)
  • options.mongoDb: MongoDB database name (default: jotai_state_store)
  • options.jsonlDir: JSONL storage directory (required if backend is jsonl)

startServer(options)

Starts the BFF server (singleton pattern). Import from bff-store/server.

  • options.port: Server port (default: 3847)

Note: Storage backend is configured by the client via remoteStorage() options, not by the server.

Package Exports

| Export | Description | Environment | |--------|-------------|-------------| | bff-store | Main entry: createStore, useStore, createNodeStore, isNode, isBrowser, memoryStorage, remoteStorage | Browser + Node.js | | bff-store/jsonl | JSONL storage adapter | Node.js only | | bff-store/mongodb | MongoDB storage adapter | Node.js only | | bff-store/server | BFF server (startServer, Router, etc.) | Node.js only |

License

MIT