# TrivialDB
[](https://travis-ci.org/trivialsoftware/trivialdb)
[](https://www.npmjs.com/package/trivialdb)

[](https://github.com/trivialsoftware/trivialdb/issues)
[](https://paypal.me/morgul/5)
TrivialDB is a lightweight key/value json storage with persistence. Conceptually, it's just a thin lodash wrapper around
plain javascript objects; with the added bonus of doing versioned asynchronous writes on changes. Its on disk format is
simply "json on disk"; basically the json version of the plain object, saved to a file on disk. This makes making hand
edits not just possible, but simple.
## Use Case
TrivialDB is intended for simple storage needs. It's in-process, small, and very, _very_ fast. It takes almost nothing
to get up and running with it, and it gives you an impressive amount of power, thanks to [lodash chaining][]. I've found
its a great fit for any personal project that needs to persist data. If you find yourself wanting to work with raw json
files, it's a rather large improvement on writing your own loading/saving/querying logic.
The one caveat to keep in mind is this: _every database your work with is stored in memory_. Since TrivialDB is in-process, you might run into the memory limits of node; before v12, on a 64 bit machine, this is 1.76GB by default. (You can increase this via `--max_old_space_size=<size>`.) In practice, however, this isn't actually that much of a limitation. Generally, you're working with a large amount of your data in memory anyway; your data sets can get relatively large before you even need to worry about this.
In fact, the very popular nosql database [Redis][redis] is in-memory. In their FAQ, they have this to say:
> In the past the Redis developers experimented with Virtual Memory and other systems in order to allow larger than RAM
datasets, but after all we are very happy if we can do one thing well: data served from memory, disk used for storage.
So for now there are no plans to create an on disk backend for Redis. Most of what Redis is, after all, is a direct
result of its current design.
In practice, I use TrivialDB to power a wiki that has thousands of printed pages worth of text, and the node process
uses around 200mb, with the json being around 1mb on disk. For things like a blog, or user database, or session storage,
or a preference system, TrivialDB will work for a long time before you need to move to something out of process.
The one caveat to keep in mind is this: _every database you work with is stored in memory_. Since TrivialDB is
in-process, you might run into the memory limits of node; (on versions before 0.12 there's a 1.4GB - 1.7GB limit).
However, this isn't actually that much of a limitation. Generally, you're working with a large amount of your
data in memory anyway; your data sets can get relatively large before you even need to worry about this.
[redis]: https://redis.io
[lodash chaining]: https://lodash.com/docs#lodash
### In-Browser Database
One of the new and exciting use cases is that TrivialDB is now usable inside a browser! By default it will read/write
JSON over REST, but you can easily change this to use IndexedDB or LocalStorage. You can even use a bundler like
Browserify or Webpack to include the JSON directly, and have zero load time.
This helps when developing static, "server-less" sites; you can have a development version that generates the JSON
locally, commit it to git, and then have your static site generation simply include the new JSON files and push them
out. Your client-side code can still work with TrivialDB as if it was a normal application.
(For more information, please see the ["Reading and Writing in a Browser"](#reading-and-writing-in-a-browser) section.)
## Lodash Shoutout
This entire project is made possible by the [lodash][] project. If it wasn't for their hard work and the effort they put
into building an amazing API, TrivialDB would not exist.
[lodash]: https://lodash.com
## Installation
Simply install with npm:
```bash
$ npm install --save trivialdb
```
## TrivialDB API
There are two concepts to remember with TrivialDB: namespaces and databases. A 'namespace' is, as it implies, just an
isolated environment with a name. Inside a namespace, all _database_ names must be unique. So, if you want to have to
independent 'foobar' databases, you will need to have them in different namespaces.
Databases, on the other hand, are the heart and soul of TrivialDB. As the name implies, they hold all your data.
Database objects are the interesting ones, with the main API you will be working with in TrivialDB.
### Creating a namespace
* `ns(name, options)` - creates or retrieves a `TDBNamespace` object.
* _alias: 'namespace'_
```javascript
const trivialdb = require('trivialdb');
// Create a namespace
const ns1 = trivialdb.ns('test-ns');
// Create a namespace with some options
const ns2 = trivialdb.ns('test-ns', { dbPath: 'server/db' });
// Create a database inside that namespace
const db = ns1.db('test', { writeToDisk: false });
```
Once you've created your namespace object, you can create or retrieve database instances from it, just like you can the
main TrivialDB module.
##### Options
The options supported by the `ns` call are:
```javascript
{
basePath: "...", // The base path for all other paths to be relative to. (Defaults to the application's base directory.)
dbPath: "..." // The path, relative to `basePath` to the root database folder. (Defaults to 'db'.)
}
```
If you call `ns` passing in the name of an existing namespace, any options passed will be ignored.
### Creating a database
* `db(name, options)` - creates or retrieves a database instance.
* _alias: 'database'_
```javascript
const trivialdb = require('trivialdb');
// Open or create a database
const db = trivialdb.db('some_db');
// Open or create a database, with options
const db2 = trivialdb.db('some_db2', { writeToDisk: false });
```
By default, when a new database is created, it will look for a file named `'some_db.json'` inside the database folder.
(By default this is `'<application rel='nofollow' onclick='return false;'>/db'`. You can control this path by setting the `basePath` or `dbPath` options of the
namespace, or alternatively, the `dbPath` or `rootPath` options of the database.)
You can request the same database multiple times, and get back the same instance (though any options passed on
subsequent calls will be ignored). This allows you to request the database by name in different places in your code,
and not worry about the two database instance fighting with each other.
##### Options
The options supported by the `db` call are:
```javascript
{
writeToDisk: true || false, // Whether or not to persist the database to disk. (Default: `true`)
loadFromDisk: true || false, // Whether or not to read the database in from disk on load. (Default: `true`)
rootPath: "...", // The path to a folder that will contain the persisted database json files. (Default: './')
dbPath: "...", // The path, relative to the namespace's `basePath` to the root database folder. (Defaults to 'db'.)
writeDelay: ..., // A number in milliseconds to wait between writes to the disk. (Default: 0)
prettyPrint: true || false, // Whether or not the json on disk should be pretty printed. (Default: `true`)
pk: "...", // The field in the object to use as the primary key. (Default: `undefined`)
idFunc: function(){...} // The function to use to generate unique ids.
}
```
If you call `db` passing in the name of an existing namespace, any options passed will be ignored.
## Namespace API
Namespaces