@bemi-io/drizzle

中文文档
0.1.0发布于 2025/11/08LGPL-3.0TypeScriptESM + CJS近 30 天下载 22万

Automatic database change tracking for Drizzle.

原始使用文档
文档目录6 节
  1. Contents
  2. Highlights
  3. Use cases
  4. Quickstart
  5. Architecture overview
  6. License

Bemi Drizzle

Bemi plugs into Drizzle and your existing PostgreSQL database to track data changes automatically. It unlocks robust context-aware audit trails and time travel querying inside your application.

Designed with simplicity and non-invasiveness in mind, Bemi doesn't require any alterations to your existing database structure. It operates in the background, empowering you with data change tracking features.

This library is an optional Drizzle integration, enabling you to pass application-specific context when performing database changes. This can include context such as the 'where' (API endpoint, worker, etc.), 'who' (user, cron job, etc.), and 'how' behind a change, thereby enriching the information captured by Bemi.

Contents

Highlights

  • Automatic and secure database change tracking with application-specific context in a structured form
  • 100% reliability in capturing data changes, even if executed through direct SQL outside the application
  • High performance without affecting code runtime execution and database workload
  • Easy-to-use without changing table structures and rewriting the code
  • Time travel querying and ability to easily group and filter changes
  • Scalability with an automatically provisioned cloud infrastructure
  • Full ownership of your data

See an example repo for Drizzle that automatically tracks all changes.

Use cases

There's a wide range of use cases that Bemi is built for! The tech was initially built as a compliance engineering system for fintech that supported $15B worth of assets under management, but has since been extracted into a general-purpose utility. Some use cases include:

  • Audit Trails: Use logs for compliance purposes or surface them to customer support and external customers.
  • Change Reversion: Revert changes made by a user or rollback all data changes within an API request.
  • Time Travel: Retrieve historical data without implementing event sourcing.
  • Troubleshooting: Identify the root cause of application issues.
  • Distributed Tracing: Track changes across distributed systems.
  • Testing: Rollback or roll-forward to different application test states.
  • Analyzing Trends: Gain insights into historical trends and changes for informed decision-making.

Quickstart

Install the NPM package

npm install @bemi-io/drizzle

Wrap your Drizzle instance and add an Express middleware to pass application context with automatically tracked database changes

import { withBemi, bemiExpressMiddleware } from "@bemi-io/drizzle";
import express, { Request } from "express";

const db = withBemi(drizzle(process.env.DATABASE_URL!));

const app = express();

app.use(
  // Customizable context
  bemiExpressMiddleware((req: Request) => ({
    userId: req.user?.id,
    endpoint: req.url,
    params: req.body,
  }))
);

Make database changes and make sure they're all stored in a table called changes in the destination DB

psql -h [HOSTNAME] -U [USERNAME] -d [DATABASE] -c 'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'

 primary_key | table | operation |                       before                      |                       after                        |                                context                                                      |      committed_at
-------------+-------+-----------+---------------------------------------------------+----------------------------------------------------+---------------------------------------------------------------------------------------------+------------------------
 26          | todo  | CREATE    | {}                                                | {"id": 26, "task": "Sleep", "isCompleted": false}  | {"userId": 187234, "endpoint": "/todo", "params": {"task": "Sleep", "isCompleted": false}}  | 2023-12-11 17:09:09+00
 27          | todo  | CREATE    | {}                                                | {"id": 27, "task": "Eat", "isCompleted": false}    | {"userId": 187234, "endpoint": "/todo", "params": {"task": "Eat", "isCompleted": false}}    | 2023-12-11 17:09:11+00
 28          | todo  | CREATE    | {}                                                | {"id": 28, "task": "Repeat", "isCompleted": false} | {"userId": 187234, "endpoint": "/todo", "params": {"task": "Repeat", "isCompleted": false}} | 2023-12-11 17:09:13+00
 26          | todo  | UPDATE    | {"id": 26, "task": "Sleep", "isCompleted": false} | {"id": 26, "task": "Sleep", "isCompleted": true}   | {"userId": 187234, "endpoint": "/todo/complete", "params": {"id": 26}}                      | 2023-12-11 17:09:15+00
 27          | todo  | DELETE    | {"id": 27, "task": "Eat", "isCompleted": false}   | {}                                                 | {"userId": 187234, "endpoint": "/todo/27", "params": {"id": 27}}                            | 2023-12-11 17:09:18+00

Check out our Drizzle docs for more details.

Architecture overview

Bemi is designed to be lightweight and secure. It takes a practical approach to achieving the benefits of event sourcing without requiring rearchitecting existing code, switching to highly specialized databases, or using unnecessary git-like abstractions on top of databases. We want your system to work the way it already does with your existing database to allow keeping things as simple as possible.

Bemi plugs into both the database and application levels, ensuring 100% reliability and a comprehensive understanding of every change.

On the database level, Bemi securely connects to PostgreSQL's Write-Ahead Log's and implements Change Data Capture. This allows tracking even the changes that get triggered via direct SQL.

On the application level, this package automatically passes application context to the replication logs to enhance the low-level database changes. For example, information about a user who made a change, an API endpoint where the change was triggered, a worker name that automatically triggered database changes, etc.

Bemi workers then stitch the low-level data with the application context and store this information in a structured easily queryable format, as depicted below:

bemi-architechture

The cloud solution includes worker ingesters, queues for fault tolerance, and a serverless PostgreSQL. If you are interested in running a self-hosted version yourself, see our self-hosting docs.

License

Distributed under the terms of the LGPL-3.0 License. If you need to modify and distribute the code, please release it to contribute back to the open-source community.

版本与发布记录

@bemi-io/drizzle 共发布 2 个版本,首次发布于 2025/11/08;过去 12 个月发布了 0 个版本。

版本发布日期距今
0.1.0latest2025/11/081 年前
1.0.02025/11/081 年前

关于 @bemi-io/drizzle 的常见问题

@bemi-io/drizzle 是什么?

Automatic database change tracking for Drizzle.

如何安装 @bemi-io/drizzle?

在项目目录运行 npm install @bemi-io/drizzle,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:express(^4.18.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 bemi,可以用 npx bemi 直接运行。

@bemi-io/drizzle 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bemi-io/drizzle 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@bemi-io/drizzle 可以商用吗?

@bemi-io/drizzle 使用 LGPL-3.0 许可。弱 Copyleft:作为库被调用时通常不要求开源你自己的代码,但修改库本身需以 LGPL 开源;前端打包合并后的适用边界存在不同理解。以上为概括,不构成法律意见,请以许可原文为准。

@bemi-io/drizzle 的下载量有多少?

根据 npm 官方下载统计,@bemi-io/drizzle 在 2026/10/08 – 2026/11/06 这 30 天内被下载 219,663 次,日均约 7,322 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bemi-io/drizzle 还在维护吗?

最新版本 0.1.0 发布于 2025/11/08(1 年前);至今共发布 2 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/11/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。