Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork956
Simple and fast JSON database
License
typicode/lowdb
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Simple to use type-safe local JSON database 🦉
If you know JavaScript, you know how to use lowdb.
Read or createdb.json
constdb=awaitJSONFilePreset('db.json',{posts:[]})
Use plain JavaScript to change data
constpost={id:1,title:'lowdb is awesome',views:100}// In two stepsdb.data.posts.push(post)awaitdb.write()// Or in oneawaitdb.update(({ posts})=>posts.push(post))
// db.json{"posts":[{"id":1,"title":"lowdb is awesome","views":100}]}
In the same spirit, query using nativeArray functions:
const{ posts}=db.dataposts.at(0)// First postposts.filter((post)=>post.title.includes('lowdb'))// Filter by titleposts.find((post)=>post.id===1)// Find by idposts.toSorted((a,b)=>a.views-b.views)// Sort by views
It's that simple.db.data is just a JavaScript object, no magic.
Become a sponsor and have your company logo here 👉GitHub Sponsors
- Lightweight
- Minimalist
- TypeScript
- Plain JavaScript
- Safe atomic writes
- Hackable:
- Change storage, file format (JSON, YAML, ...) or add encryption viaadapters
- Extend it with lodash, ramda, ... for super powers!
- Automatically switches to fast in-memory mode during tests
npm install lowdb
Lowdb is a pure ESM package. If you're having trouble using it in your project, pleaseread this.
import{JSONFilePreset}from'lowdb/node'// Read or create db.jsonconstdefaultData={posts:[]}constdb=awaitJSONFilePreset('db.json',defaultData)// Update db.jsonawaitdb.update(({ posts})=>posts.push('hello world'))// Alternatively you can call db.write() explicitely later// to write to db.jsondb.data.posts.push('hello world')awaitdb.write()
// db.json{"posts":["hello world"]}
You can use TypeScript to check your data types.
typeData={messages:string[]}constdefaultData:Data={messages:[]}constdb=awaitJSONPreset<Data>('db.json',defaultData)db.data.messages.push('foo')// ✅ Successdb.data.messages.push(1)// ❌ TypeScript error
You can extend lowdb with Lodash (or other libraries). To be able to extend it, we're not usingJSONPreset here. Instead, we're using lower components.
import{Low}from'lowdb'import{JSONFile}from'lowdb/node'importlodashfrom'lodash'typePost={id:numbertitle:string}typeData={posts:Post[]}// Extend Low class with a new `chain` fieldclassLowWithLodash<T>extendsLow<T>{chain:lodash.ExpChain<this['data']>=lodash.chain(this).get('data')}constdefaultData:Data={posts:[],}constadapter=newJSONFile<Data>('db.json')constdb=newLowWithLodash(adapter,defaultData)awaitdb.read()// Instead of db.data use db.chain to access lodash APIconstpost=db.chain.get('posts').find({id:1}).value()// Important: value() must be called to execute chain
Seesrc/examples/ directory.
Lowdb provides four presets for common cases.
JSONFilePreset(filename, defaultData)JSONFileSyncPreset(filename, defaultData)LocalStoragePreset(name, defaultData)SessionStoragePreset(name, defaultData)
Seesrc/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.
Lowdb has two classes (for asynchronous and synchronous adapters).
import{Low}from'lowdb'import{JSONFile}from'lowdb/node'constdb=newLow(newJSONFile('file.json'),{})awaitdb.read()awaitdb.write()
import{LowSync}from'lowdb'import{JSONFileSync}from'lowdb/node'constdb=newLowSync(newJSONFileSync('file.json'),{})db.read()db.write()
Callsadapter.read() and setsdb.data.
Note:JSONFile andJSONFileSync adapters will setdb.data tonull if file doesn't exist.
db.data// === nulldb.read()db.data// !== null
Callsadapter.write(db.data).
db.data={posts:[]}db.write()// file.json will be { posts: [] }db.data={}db.write()// file.json will be {}
Callsfn() thendb.write().
db.update((data)=>{// make changes to data// ...})// files.json will be updated
Holds your db content. If you're using the adapters coming with lowdb, it can be any type supported byJSON.stringify.
For example:
db.data='string'db.data=[1,2,3]db.data={key:'value'}
Adapters for reading and writing JSON files.
import{JSONFile,JSONFileSync}from'lowdb/node'newLow(newJSONFile(filename),{})newLowSync(newJSONFileSync(filename),{})
In-memory adapters. Useful for speeding up unit tests. Seesrc/examples/ directory.
import{Memory,MemorySync}from'lowdb'newLow(newMemory(),{})newLowSync(newMemorySync(),{})
Synchronous adapter forwindow.localStorage andwindow.sessionStorage.
import{LocalStorage,SessionStorage}from'lowdb/browser'newLowSync(newLocalStorage(name),{})newLowSync(newSessionStorage(name),{})
Adapters for reading and writing text. Useful for creating custom adapters.
Adapters for easily supporting other data formats or adding behaviors (encrypt, compress...).
import{DataFile}from'lowdb/node'newDataFile(filename,{parse:YAML.parse,stringify:YAML.stringify})newDataFile(filename,{parse:(data)=>{decypt(JSON.parse(data))},stringify:(str)=>{encrypt(JSON.stringify(str))}})
If you've published an adapter for lowdb, feel free to create a PR to add it here.
You may want to create an adapter to writedb.data to YAML, XML, encrypt data, a remote storage, ...
An adapter is a simple class that just needs to expose two methods:
classAsyncAdapter{read(){/* ... */}// should return Promise<data>write(data){/* ... */}// should return Promise<void>}classSyncAdapter{read(){/* ... */}// should return datawrite(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'classCustomAsyncAdapter{// Optional: your adapter can take argumentsconstructor(args){// ...}asyncread(){constdata=awaitapi.read()returndata}asyncwrite(data){awaitapi.write(data)}}constadapter=newCustomAsyncAdapter()constdb=newLow(adapter,{})
Seesrc/adapters/ for more examples.
To create an adapter for another format than JSON, you can useTextFile orTextFileSync.
For example:
import{Adapter,Low}from'lowdb'import{TextFile}from'lowdb/node'importYAMLfrom'yaml'classYAMLFile{constructor(filename){this.adapter=newTextFile(filename)}asyncread(){constdata=awaitthis.adapter.read()if(data===null){returnnull}else{returnYAML.parse(data)}}write(obj){returnthis.adapter.write(YAML.stringify(obj))}}constadapter=newYAMLFile('file.yaml')constdb=newLow(adapter,{})
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 calldb.write, the wholedb.data is serialized usingJSON.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 callingdb.write only when you need it.
If you plan to scale, it's highly recommended to use databases like PostgreSQL or MongoDB instead.
About
Simple and fast JSON database
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.