{"id":13403851,"url":"https://github.com/typicode/lowdb","last_synced_at":"2025-05-12T22:34:35.333Z","repository":{"id":15615403,"uuid":"18351848","full_name":"typicode/lowdb","owner":"typicode","description":"Simple and fast JSON database","archived":false,"fork":false,"pushed_at":"2024-06-16T09:51:11.000Z","size":1208,"stargazers_count":22029,"open_issues_count":14,"forks_count":949,"subscribers_count":243,"default_branch":"main","last_synced_at":"2025-05-05T17:21:34.632Z","etag":null,"topics":["database","electron","embeddable","embedded-database","javascript","json","localstorage","lodash","nodejs","storage"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/typicode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"typicode"}},"created_at":"2014-04-02T02:16:06.000Z","updated_at":"2025-05-05T17:07:01.000Z","dependencies_parsed_at":"2023-02-18T00:55:23.377Z","dependency_job_id":"7a5fbcd0-98a8-470f-bf80-c2f977c4bd18","html_url":"https://github.com/typicode/lowdb","commit_stats":{"total_commits":510,"total_committers":42,"mean_commits":"12.142857142857142","dds":"0.12549019607843137","last_synced_commit":"31458f3173f133d153afc5a8dfb5a76eaa1c7b66"},"previous_names":[],"tags_count":77,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Flowdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Flowdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Flowdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Flowdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typicode","download_url":"https://codeload.github.com/typicode/lowdb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253834385,"owners_count":21971604,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","electron","embeddable","embedded-database","javascript","json","localstorage","lodash","nodejs","storage"],"created_at":"2024-07-30T19:01:35.453Z","updated_at":"2025-05-12T22:34:35.241Z","avatar_url":"https://github.com/typicode.png","language":"JavaScript","readme":"# lowdb [![](http://img.shields.io/npm/dm/lowdb.svg?style=flat)](https://www.npmjs.org/package/lowdb) [![Node.js CI](https://github.com/typicode/lowdb/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/lowdb/actions/workflows/node.js.yml)\n\n\u003e Simple to use type-safe local JSON database 🦉\n\u003e \n\u003e If you know JavaScript, you know how to use lowdb.\n\nRead or create `db.json`\n\n```js\nconst db = await JSONFilePreset('db.json', { posts: [] })\n```\n\nUse plain JavaScript to change data\n\n```js\nconst post = { id: 1, title: 'lowdb is awesome', views: 100 }\n\n// In two steps\ndb.data.posts.push(post)\nawait db.write()\n\n// Or in one\nawait db.update(({ posts }) =\u003e posts.push(post))\n```\n\n```js\n// db.json\n{\n  \"posts\": [\n    { \"id\": 1, \"title\": \"lowdb is awesome\", \"views\": 100 }\n  ]\n}\n```\n\nIn the same spirit, query using native `Array` functions:\n\n```js\nconst { posts } = db.data\n\nposts.at(0) // First post\nposts.filter((post) =\u003e post.title.includes('lowdb')) // Filter by title\nposts.find((post) =\u003e post.id === 1) // Find by id\nposts.toSorted((a, b) =\u003e a.views - b.views) // Sort by views\n```\n\nIt's that simple. `db.data` is just a JavaScript object, no magic.\n\n## Sponsors\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://mockend.com/\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://jsonplaceholder.typicode.com/mockend.svg\" height=\"70px\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n[Become a sponsor and have your company logo here](https://github.com/sponsors/typicode) 👉 [GitHub Sponsors](https://github.com/sponsors/typicode)\n\n## Features\n\n- **Lightweight**\n- **Minimalist**\n- **TypeScript**\n- **Plain JavaScript**\n- Safe atomic writes\n- Hackable:\n  - Change storage, file format (JSON, YAML, ...) or add encryption via [adapters](#adapters)\n  - Extend it with lodash, ramda, ... for super powers!\n- Automatically switches to fast in-memory mode during tests\n\n## Install\n\n```sh\nnpm install lowdb\n```\n\n## Usage\n\n_Lowdb is a pure ESM package. If you're having trouble using it in your project, please [read this](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)._\n\n```js\nimport { JSONFilePreset } from 'lowdb/node'\n\n// Read or create db.json\nconst defaultData = { posts: [] }\nconst db = await JSONFilePreset('db.json', defaultData)\n\n// Update db.json\nawait db.update(({ posts }) =\u003e posts.push('hello world'))\n\n// Alternatively you can call db.write() explicitely later\n// to write to db.json\ndb.data.posts.push('hello world')\nawait db.write()\n```\n\n```js\n// db.json\n{\n  \"posts\": [ \"hello world\" ]\n}\n```\n\n### TypeScript\n\nYou can use TypeScript to check your data types.\n\n```ts\ntype Data = {\n  messages: string[]\n}\n\nconst defaultData: Data = { messages: [] }\nconst db = await JSONPreset\u003cData\u003e('db.json', defaultData)\n\ndb.data.messages.push('foo') // ✅ Success\ndb.data.messages.push(1) // ❌ TypeScript error\n```\n\n### Lodash\n\nYou 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.\n\n```ts\nimport { Low } from 'lowdb'\nimport { JSONFile } from 'lowdb/node'\nimport lodash from 'lodash'\n\ntype Post = {\n  id: number\n  title: string\n}\n\ntype Data = {\n  posts: Post[]\n}\n\n// Extend Low class with a new `chain` field\nclass LowWithLodash\u003cT\u003e extends Low\u003cT\u003e {\n  chain: lodash.ExpChain\u003cthis['data']\u003e = lodash.chain(this).get('data')\n}\n\nconst defaultData: Data = {\n  posts: [],\n}\nconst adapter = new JSONFile\u003cData\u003e('db.json', defaultData)\n\nconst db = new LowWithLodash(adapter)\nawait db.read()\n\n// Instead of db.data use db.chain to access lodash API\nconst post = db.chain.get('posts').find({ id: 1 }).value() // Important: value() must be called to execute chain\n```\n\n### CLI, Server, Browser and in tests usage\n\nSee [`src/examples/`](src/examples) directory.\n\n## API\n\n### Presets\n\nLowdb provides four presets for common cases.\n\n- `JSONFilePreset(filename, defaultData)`\n- `JSONFileSyncPreset(filename, defaultData)`\n- `LocalStoragePreset(name, defaultData)`\n- `SessionStoragePreset(name, defaultData)`\n\nSee [`src/examples/`](src/examples) directory for usage.\n\nLowdb is extremely flexible, if you need to extend it or modify its behavior, use the classes and adapters below instead of the presets.\n\n### Classes\n\nLowdb has two classes (for asynchronous and synchronous adapters).\n\n#### `new Low(adapter, defaultData)`\n\n```js\nimport { Low } from 'lowdb'\nimport { JSONFile } from 'lowdb/node'\n\nconst db = new Low(new JSONFile('file.json'), {})\nawait db.read()\nawait db.write()\n```\n\n#### `new LowSync(adapterSync, defaultData)`\n\n```js\nimport { LowSync } from 'lowdb'\nimport { JSONFileSync } from 'lowdb/node'\n\nconst db = new LowSync(new JSONFileSync('file.json'), {})\ndb.read()\ndb.write()\n```\n\n### Methods\n\n#### `db.read()`\n\nCalls `adapter.read()` and sets `db.data`.\n\n**Note:** `JSONFile` and `JSONFileSync` adapters will set `db.data` to `null` if file doesn't exist.\n\n```js\ndb.data // === null\ndb.read()\ndb.data // !== null\n```\n\n#### `db.write()`\n\nCalls `adapter.write(db.data)`.\n\n```js\ndb.data = { posts: [] }\ndb.write() // file.json will be { posts: [] }\ndb.data = {}\ndb.write() // file.json will be {}\n```\n\n#### `db.update(fn)`\n\nCalls `fn()` then `db.write()`.\n\n```js\ndb.update((data) =\u003e {\n  // make changes to data\n  // ...\n})\n// files.json will be updated\n```\n\n### Properties\n\n#### `db.data`\n\nHolds your db content. If you're using the adapters coming with lowdb, it can be any type supported by [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).\n\nFor example:\n\n```js\ndb.data = 'string'\ndb.data = [1, 2, 3]\ndb.data = { key: 'value' }\n```\n\n## Adapters\n\n### Lowdb adapters\n\n#### `JSONFile` `JSONFileSync`\n\nAdapters for reading and writing JSON files.\n\n```js\nimport { JSONFile, JSONFileSync } from 'lowdb/node'\n\nnew Low(new JSONFile(filename), {})\nnew LowSync(new JSONFileSync(filename), {})\n```\n\n#### `Memory` `MemorySync`\n\nIn-memory adapters. Useful for speeding up unit tests. See [`src/examples/`](src/examples) directory.\n\n```js\nimport { Memory, MemorySync } from 'lowdb'\n\nnew Low(new Memory(), {})\nnew LowSync(new MemorySync(), {})\n```\n\n#### `LocalStorage` `SessionStorage`\n\nSynchronous adapter for `window.localStorage` and `window.sessionStorage`.\n\n```js\nimport { LocalStorage, SessionStorage } from 'lowdb/browser'\nnew LowSync(new LocalStorage(name), {})\nnew LowSync(new SessionStorage(name), {})\n```\n\n### Utility adapters\n\n#### `TextFile` `TextFileSync`\n\nAdapters for reading and writing text. Useful for creating custom adapters.\n\n#### `DataFile` `DataFileSync`\n\nAdapters for easily supporting other data formats or adding behaviors (encrypt, compress...).\n\n```js\nimport { DataFile } from 'lowdb/node'\nnew DataFile(filename, {\n  parse: YAML.parse,\n  stringify: YAML.stringify\n})\nnew DataFile(filename, {\n  parse: (data) =\u003e { decypt(JSON.parse(data)) },\n  stringify: (str) =\u003e { encrypt(JSON.stringify(str)) }\n})\n```\n\n### Third-party adapters\n\nIf you've published an adapter for lowdb, feel free to create a PR to add it here.\n\n### Writing your own adapter\n\nYou may want to create an adapter to write `db.data` to YAML, XML, encrypt data, a remote storage, ...\n\nAn adapter is a simple class that just needs to expose two methods:\n\n```js\nclass AsyncAdapter {\n  read() {\n    /* ... */\n  } // should return Promise\u003cdata\u003e\n  write(data) {\n    /* ... */\n  } // should return Promise\u003cvoid\u003e\n}\n\nclass SyncAdapter {\n  read() {\n    /* ... */\n  } // should return data\n  write(data) {\n    /* ... */\n  } // should return nothing\n}\n```\n\nFor example, let's say you have some async storage and want to create an adapter for it:\n\n```js\nimport { Low } from 'lowdb'\nimport { api } from './AsyncStorage'\n\nclass CustomAsyncAdapter {\n  // Optional: your adapter can take arguments\n  constructor(args) {\n    // ...\n  }\n\n  async read() {\n    const data = await api.read()\n    return data\n  }\n\n  async write(data) {\n    await api.write(data)\n  }\n}\n\nconst adapter = new CustomAsyncAdapter()\nconst db = new Low(adapter, {})\n```\n\nSee [`src/adapters/`](src/adapters) for more examples.\n\n#### Custom serialization\n\nTo create an adapter for another format than JSON, you can use `TextFile` or `TextFileSync`.\n\nFor example:\n\n```js\nimport { Adapter, Low } from 'lowdb'\nimport { TextFile } from 'lowdb/node'\nimport YAML from 'yaml'\n\nclass YAMLFile {\n  constructor(filename) {\n    this.adapter = new TextFile(filename)\n  }\n\n  async read() {\n    const data = await this.adapter.read()\n    if (data === null) {\n      return null\n    } else {\n      return YAML.parse(data)\n    }\n  }\n\n  write(obj) {\n    return this.adapter.write(YAML.stringify(obj))\n  }\n}\n\nconst adapter = new YAMLFile('file.yaml')\nconst db = new Low(adapter, {})\n```\n\n## Limits\n\nLowdb doesn't support Node's cluster module.\n\nIf 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.\n\nDepending 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.\n\nIf you plan to scale, it's highly recommended to use databases like PostgreSQL or MongoDB instead.\n","funding_links":["https://github.com/sponsors/typicode"],"categories":["JavaScript","Packages","Repository","Databases","包","目录","数据库管理系统","Database","database","Utilities","nodejs","Electron Tools, Libraries, and Frameworks","Tools","前端常用","3. 模拟数据( Mock )"],"sub_categories":["Database","数据库","网络服务_其他","React Components","Mesh networks","JavaScript Libraries for Machine Learning","24.3 Web Sockets"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypicode%2Flowdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftypicode%2Flowdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypicode%2Flowdb/lists"}