lowdb README

The project's README from github.com/typicode/lowdb. As one markdown file: README.md.

lowdb Node.js CI

Simple to use type-safe local JSON database 🦉

If you know JavaScript, you know how to use lowdb.

Read or create db.json

const db = await JSONFilePreset('db.json', { posts: [] })

Use plain JavaScript to change data

const post = { id: 1, title: 'lowdb is awesome', views: 100 }

// In two steps
db.data.posts.push(post)
await db.write()

// Or in one
await db.update(({ posts }) => posts.push(post))
// db.json
{
  "posts": [
    { "id": 1, "title": "lowdb is awesome", "views": 100 }
  ]
}

In the same spirit, query using native Array functions:

const { posts } = db.data

posts.at(0) // First post
posts.filter((post) => post.title.includes('lowdb')) // Filter by title
posts.find((post) => post.id === 1) // Find by id
posts.toSorted((a, b) => a.views - b.views) // Sort by views

It's that simple. db.data is just a JavaScript object, no magic.

Sponsors





Become a sponsor and have your company logo here 👉 GitHub Sponsors

Features

Install

npm install lowdb

Usage

Lowdb is a pure ESM package. If you're having trouble using it in your project, please read this.

import { JSONFilePreset } from 'lowdb/node'

// Read or create db.json
const defaultData = { posts: [] }
const db = await JSONFilePreset('db.json', defaultData)

// Update db.json
await db.update(({ posts }) => posts.push('hello world'))

// Alternatively you can call db.write() explicitely later
// to write to db.json
db.data.posts.push('hello world')
await db.write()
// db.json
{
  "posts": [ "hello world" ]
}

TypeScript

You can use TypeScript to check your data types.

type Data = {
  messages: string[]
}

const defaultData: Data = { messages: [] }
const db = await JSONPreset<Data>('db.json', defaultData)

db.data.messages.push('foo') // ✅ Success
db.data.messages.push(1) // ❌ TypeScript error

Lodash

You can extend lowdb with Lodash (or other libraries). To be able to extend it, we're not using JSONPreset here. Instead, we're using lower components.

import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node'
import lodash from 'lodash'

type Post = {
  id: number
  title: string
}

type Data = {
  posts: Post[]
}

// Extend Low class with a new `chain` field
class LowWithLodash<T> extends Low<T> {
  chain: lodash.ExpChain<this['data']> = lodash.chain(this).get('data')
}

const defaultData: Data = {
  posts: [],
}
const adapter = new JSONFile<Data>('db.json')

const db = new LowWithLodash(adapter, defaultData)
await db.read()

// Instead of db.data use db.chain to access lodash API
const post = db.chain.get('posts').find({ id: 1 }).value() // Important: value() must be called to execute chain

CLI, Server, Browser and in tests usage

See src/examples/ directory.

API

Presets

Lowdb provides four presets for common cases.

See src/examples/ directory for usage.

Lowdb is extremely flexible, if you need to extend it or modify its behavior, use the classes and adapters below instead of the presets.

Classes

Lowdb has two classes (for asynchronous and synchronous adapters).

new Low(adapter, defaultData)

import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node'

const db = new Low(new JSONFile('file.json'), {})
await db.read()
await db.write()

new LowSync(adapterSync, defaultData)

import { LowSync } from 'lowdb'
import { JSONFileSync } from 'lowdb/node'

const db = new LowSync(new JSONFileSync('file.json'), {})
db.read()
db.write()

Methods

db.read()

Calls adapter.read() and sets db.data.

Note: JSONFile and JSONFileSync adapters will set db.data to null if file doesn't exist.

db.data // === null
db.read()
db.data // !== null

db.write()

Calls adapter.write(db.data).

db.data = { posts: [] }
db.write() // file.json will be { posts: [] }
db.data = {}
db.write() // file.json will be {}

db.update(fn)

Calls fn() then db.write().

db.update((data) => {
  // make changes to data
  // ...
})
// files.json will be updated

Properties

db.data

Holds your db content. If you're using the adapters coming with lowdb, it can be any type supported by JSON.stringify.

For example:

db.data = 'string'
db.data = [1, 2, 3]
db.data = { key: 'value' }

Adapters

Lowdb adapters

JSONFile JSONFileSync

Adapters for reading and writing JSON files.

import { JSONFile, JSONFileSync } from 'lowdb/node'

new Low(new JSONFile(filename), {})
new LowSync(new JSONFileSync(filename), {})

Memory MemorySync

In-memory adapters. Useful for speeding up unit tests. See src/examples/ directory.

import { Memory, MemorySync } from 'lowdb'

new Low(new Memory(), {})
new LowSync(new MemorySync(), {})

LocalStorage SessionStorage

Synchronous adapter for window.localStorage and window.sessionStorage.

import { LocalStorage, SessionStorage } from 'lowdb/browser'
new LowSync(new LocalStorage(name), {})
new LowSync(new SessionStorage(name), {})

Utility adapters

TextFile TextFileSync

Adapters for reading and writing text. Useful for creating custom adapters.

DataFile DataFileSync

Adapters for easily supporting other data formats or adding behaviors (encrypt, compress...).

import { DataFile } from 'lowdb/node'
new DataFile(filename, {
  parse: YAML.parse,
  stringify: YAML.stringify
})
new DataFile(filename, {
  parse: (data) => { decypt(JSON.parse(data)) },
  stringify: (str) => { encrypt(JSON.stringify(str)) }
})

Third-party adapters

If you've published an adapter for lowdb, feel free to create a PR to add it here.

Writing your own adapter

You may want to create an adapter to write db.data to YAML, XML, encrypt data, a remote storage, ...

An adapter is a simple class that just needs to expose two methods:

class AsyncAdapter {
  read() {
    /* ... */
  } // should return Promise<data>
  write(data) {
    /* ... */
  } // should return Promise<void>
}

class SyncAdapter {
  read() {
    /* ... */
  } // should return data
  write(data) {
    /* ... */
  } // should return nothing
}

For example, let's say you have some async storage and want to create an adapter for it:

import { Low } from 'lowdb'
import { api } from './AsyncStorage'

class CustomAsyncAdapter {
  // Optional: your adapter can take arguments
  constructor(args) {
    // ...
  }

  async read() {
    const data = await api.read()
    return data
  }

  async write(data) {
    await api.write(data)
  }
}

const adapter = new CustomAsyncAdapter()
const db = new Low(adapter, {})

See src/adapters/ for more examples.

Custom serialization

To create an adapter for another format than JSON, you can use TextFile or TextFileSync.

For example:

import { Adapter, Low } from 'lowdb'
import { TextFile } from 'lowdb/node'
import YAML from 'yaml'

class YAMLFile {
  constructor(filename) {
    this.adapter = new TextFile(filename)
  }

  async read() {
    const data = await this.adapter.read()
    if (data === null) {
      return null
    } else {
      return YAML.parse(data)
    }
  }

  write(obj) {
    return this.adapter.write(YAML.stringify(obj))
  }
}

const adapter = new YAMLFile('file.yaml')
const db = new Low(adapter, {})

Limits

Lowdb doesn't support Node's cluster module.

If you have large JavaScript objects (~10-100MB) you may hit some performance issues. This is because whenever you call db.write, the whole db.data is serialized using JSON.stringify and written to storage.

Depending on your use case, this can be fine or not. It can be mitigated by doing batch operations and calling db.write only when you need it.

If you plan to scale, it's highly recommended to use databases like PostgreSQL or MongoDB instead.

lowdb (typicode/lowdb)

Searching Database…

22.6K ·GitHub
这是什么?lowdb 是一个用于 JavaScript 的小巧且类型安全的本地 JSON 数据库:你可以读取或创建一个 db.json 文件,然后用普通的 JavaScript(包括原生的数组方法)来修改数据。
也就是说它是一个我安装的库,而不是需要我运行起来的数据库服务器?它是一个从 npm 安装的库,不是服务器。没有任何需要运行的进程——db.data 就是一个普通的 JavaScript 对象,lowdb 会让它和 JSON 文件自动保持同步。
在项目里我该怎么开始使用它?先运行 npm install lowdb,然后用 JSONFilePreset('db.json', defaultData) 创建数据库。之后用 db.update(fn) 修改数据并自动写入文件,或者手动调用 db.read() 和 db.write()。
除了 npm 之外还需要装别的东西吗?只需要 Node.js 18 或更高版本——它是一个纯 ESM 包,运行时只依赖一个包(steno),不需要任何数据库二进制程序或后台服务。
在决定用它之前,有什么限制我需要了解吗?它不支持 Node 的 cluster 模块,而且大对象(约 10-100MB)会变慢,因为每次 db.write 都会用 JSON.stringify 序列化整个数据库。如果你打算做大规模扩展,README 建议改用 PostgreSQL 或 MongoDB。
在浏览器里也能用它吗?可以。除了 Node.js,它还提供了针对 window.localStorage 和 window.sessionStorage 的 LocalStorage 和 SessionStorage 预设,README 里还有 CLI、Server 和 Browser 的示例。
我的数据到底存在哪里?存在磁盘上一个由你自己掌控的普通 JSON 文件里(默认是 db.json)。不会有任何东西在云端运行——没有服务器、没有账号,也没有遥测。
我可以用 TypeScript 来使用它吗?可以——lowdb 是类型安全的,你可以用 TypeScript 类型来描述 db.data,并在编译阶段就发现数据结构上的错误。
它能用其他格式保存数据吗,比如 YAML?可以,通过适配器实现:lowdb 自带 TextFile 和 DataFile 两个工具适配器,自定义适配器也只需要一个包含两个方法的类,所以它可以对接 YAML、XML、加密、压缩或远程存储。
我可以配合 Lodash 或 Ramda 使用吗?可以。不用 JSONPreset 这个快捷方式,改用更底层的类,然后按照 README 的建议用 Lodash 或 Ramda 来扩展你的查询。
跑测试的时候会怎样?它在测试期间会自动切换到快速的内存模式,另外也有专门用于这个目的的 Memory 和 MemorySync 适配器。
Creator
typicode
Size
1.1 MB
Stars
22.6K
Age
12y
Commits · 90 Days