UNPKG

8.58 kBMarkdownView Raw
1# Lowdb
2
3[![](http://img.shields.io/npm/dm/lowdb.svg?style=flat)](https://www.npmjs.org/package/lowdb) [![NPM version](https://badge.fury.io/js/lowdb.svg)](http://badge.fury.io/js/lowdb) [![Build Status](https://travis-ci.org/typicode/lowdb.svg?branch=master)](https://travis-ci.org/typicode/lowdb) [![Donate](https://img.shields.io/badge/patreon-donate-ff69b4.svg)](https://www.patreon.com/typicode)
4
5> Small JSON database for Node, Electron and the browser. Powered by Lodash. :zap:
6
7```js
8db.get('posts')
9 .push({ id: 1, title: 'lowdb is awesome'})
10 .write()
11```
12
13## Usage
14
15```sh
16npm install lowdb
17```
18
19```js
20const low = require('lowdb')
21const FileSync = require('lowdb/adapters/FileSync')
22
23const adapter = new FileSync('db.json')
24const db = low(adapter)
25
26// Set some defaults
27db.defaults({ posts: [], user: {} })
28 .write()
29
30// Add a post
31db.get('posts')
32 .push({ id: 1, title: 'lowdb is awesome'})
33 .write()
34
35// Set a user using Lodash shorthand syntax
36db.set('user.name', 'typicode')
37 .write()
38```
39
40Data is saved to `db.json`
41
42```json
43{
44 "posts": [
45 { "id": 1, "title": "lowdb is awesome"}
46 ],
47 "user": {
48 "name": "typicode"
49 }
50}
51```
52
53You can use any [lodash](https://lodash.com/docs) function like [`_.get`](https://lodash.com/docs#get) and [`_.find`](https://lodash.com/docs#find) with shorthand syntax.
54
55```js
56// Use .value() instead of .write() if you're only reading from db
57db.get('posts')
58 .find({ id: 1 })
59 .value()
60```
61
62Lowdb is perfect for CLIs, small servers, Electron apps and npm packages in general.
63
64It supports __Node__, the __browser__ and uses __lodash API__, so it's very simple to learn. Actually, if you know Lodash, you already know how to use lowdb :wink:
65
66* [Usage examples](https://github.com/typicode/lowdb/tree/master/examples)
67 * [CLI](https://github.com/typicode/lowdb/tree/master/examples#cli)
68 * [Browser](https://github.com/typicode/lowdb/tree/master/examples#browser)
69 * [Server](https://github.com/typicode/lowdb/tree/master/examples#server)
70 * [In-memory](https://github.com/typicode/lowdb/tree/master/examples#in-memory)
71* [JSFiddle live example](https://jsfiddle.net/typicode/4kd7xxbu/)
72
73__Important__ lowdb doesn't support Cluster and may have issues with very large JSON files (~200MB).
74
75## Install
76
77```sh
78npm install lowdb
79```
80
81Alternatively, if you're using [yarn](https://yarnpkg.com/)
82
83```sh
84yarn add lowdb
85```
86
87A UMD build is also available on [unpkg](https://unpkg.com/) for testing and quick prototyping:
88
89```html
90<script src="https://unpkg.com/lodash@4/lodash.min.js"></script>
91<script src="https://unpkg.com/lowdb@0.17/dist/low.min.js"></script>
92<script src="https://unpkg.com/lowdb@0.17/dist/LocalStorage.min.js"></script>
93<script>
94 var adapter = new LocalStorage('db')
95 var db = low(adapter)
96</script>
97```
98
99## API
100
101__low(adapter)__
102
103Returns a lodash [chain](https://lodash.com/docs/4.17.4#chain) with additional properties and functions described below.
104
105__db.[...].write()__
106
107__db.[...].value()__
108
109`write()` is syntactic sugar for calling `value()` and `db.write()` in one line.
110
111On the other hand, `value()` is just [\_.protoype.value()](https://lodash.com/docs/4.17.4#prototype-value) and should be used to execute a chain that doesn't change database state.
112
113
114```js
115db.set('user.name', 'typicode')
116 .write()
117
118// is equivalent to
119db.set('user.name', 'typicode')
120 .value()
121
122db.write()
123```
124
125__db.___
126
127Database lodash instance. Use it to add your own utility functions or third-party mixins like [underscore-contrib](https://github.com/documentcloud/underscore-contrib) or [lodash-id](https://github.com/typicode/lodash-id).
128
129```js
130db._.mixin({
131 second: function(array) {
132 return array[1]
133 }
134})
135
136db.get('posts')
137 .second()
138 .value()
139```
140
141__db.getState()__
142
143Returns database state.
144
145```js
146db.getState() // { posts: [ ... ] }
147```
148
149__db.setState(newState)__
150
151Replaces database state.
152
153```js
154const newState = {}
155db.setState(newState)
156```
157
158__db.write()__
159
160Persists database using `adapter.write` (depending on the adapter, may return a promise).
161
162```js
163// With lowdb/adapters/FileSync
164db.write()
165console.log('State has been saved')
166
167// With lowdb/adapters/FileAsync
168db.write()
169 .then(() => console.log('State has been saved'))
170```
171
172__db.read()__
173
174Reads source using `storage.read` option (depending on the adapter, may return a promise).
175
176```js
177// With lowdb/FileSync
178db.read()
179console.log('State has been updated')
180
181// With lowdb/FileAsync
182db.write()
183 .then(() => console.log('State has been updated'))
184```
185
186## Adapters API
187
188Please note this only applies to adapters bundled with Lowdb. Third-party adapters may have different options.
189
190For convenience, `FileSync`, `FileAsync` and `LocalBrowser` accept the following options:
191
192* __defaultValue__ if file doesn't exist, this value will be used to set the initial state (default: `{}`)
193* __serialize/deserialize__ functions used before writing and after reading (default: `JSON.stringify` and `JSON.parse`)
194
195```js
196const adapter = new FileSync('array.yaml', {
197 defaultValue: [],
198 serialize: (array) => toYamlString(array),
199 deserialize: (string) => fromYamlString(string)
200})
201```
202
203## Guide
204
205### How to query
206
207With lowdb, you get access to the entire [lodash API](http://lodash.com/), so there are many ways to query and manipulate data. Here are a few examples to get you started.
208
209Please note that data is returned by reference, this means that modifications to returned objects may change the database. To avoid such behaviour, you need to use `.cloneDeep()`.
210
211Also, the execution of methods is lazy, that is, execution is deferred until `.value()` or `.write()` is called.
212
213#### Examples
214
215Check if posts exists.
216
217```js
218db.has('posts')
219 .value()
220```
221
222Set posts.
223
224```js
225db.set('posts', [])
226 .write()
227```
228
229
230Sort the top five posts.
231
232```js
233db.get('posts')
234 .filter({published: true})
235 .sortBy('views')
236 .take(5)
237 .value()
238```
239
240Get post titles.
241
242```js
243db.get('posts')
244 .map('title')
245 .value()
246```
247
248Get the number of posts.
249
250```js
251db.get('posts')
252 .size()
253 .value()
254```
255
256Get the title of first post using a path.
257
258```js
259db.get('posts[0].title')
260 .value()
261```
262
263Update a post.
264
265```js
266db.get('posts')
267 .find({ title: 'low!' })
268 .assign({ title: 'hi!'})
269 .write()
270```
271
272Remove posts.
273
274```js
275db.get('posts')
276 .remove({ title: 'low!' })
277 .write()
278```
279
280Remove a property.
281
282```js
283db.unset('user.name')
284 .write()
285```
286
287Make a deep clone of posts.
288
289```js
290db.get('posts')
291 .cloneDeep()
292 .value()
293```
294
295### How to use id based resources
296
297Being able to get data using an id can be quite useful, particularly in servers. To add id-based resources support to lowdb, you have 2 options.
298
299[shortid](https://github.com/dylang/shortid) is more minimalist and returns a unique id that you can use when creating resources.
300
301```js
302const shortid = require('shortid')
303
304const postId = db
305 .get('posts')
306 .push({ id: shortid.generate(), title: 'low!' })
307 .write()
308 .id
309
310const post = db
311 .get('posts')
312 .find({ id: postId })
313 .value()
314```
315
316[lodash-id](https://github.com/typicode/lodash-id) provides a set of helpers for creating and manipulating id-based resources.
317
318```js
319const lodashId = require('lodash-id')
320const db = low('db.json')
321
322db._.mixin(lodashId)
323
324const post = db
325 .get('posts')
326 .insert({ title: 'low!' })
327 .write()
328
329const post = db
330 .get('posts')
331 .getById(post.id)
332 .value()
333```
334
335### How to create custom adapters
336
337`low()` accepts custom Adapter, so you can virtually save your data to any storage using any format.
338
339```js
340class MyStorage {
341 constructor() {
342 // ...
343 }
344
345 read() {
346 // Should return data (object or array) or a Promise
347 }
348
349 write(data) {
350 // Should return nothing or a Promise
351 }
352}
353
354const adapter = new MyStorage(args)
355const db = low()
356```
357
358See [src/adapters](src/adapters) for examples.
359
360### How to encrypt data
361
362`FileSync`, `FileAsync` and `LocalStorage` accept custom `serialize` and `deserialize` functions. You can use them to add encryption logic.
363
364```js
365const adapter = new FileSync('db.json', {
366 serialize: (data) => encrypt(JSON.stringify(data))
367 deserialize: (data) => JSON.parse(decrypt(data))
368})
369```
370
371## Changelog
372
373See changes for each version in the [release notes](https://github.com/typicode/lowdb/releases).
374
375## Limits
376
377Lowdb is a convenient method for storing data without setting up a database server. It is fast enough and safe to be used as an embedded database.
378
379However, if you seek high performance and scalability more than simplicity, you should probably stick to traditional databases like MongoDB.
380
381## License
382
383MIT - [Typicode :cactus:](https://github.com/typicode)