{"id":13989847,"url":"https://github.com/trivialsoftware/trivialdb","last_synced_at":"2025-07-22T11:31:51.318Z","repository":{"id":16835737,"uuid":"19595246","full_name":"trivialsoftware/trivialdb","owner":"trivialsoftware","description":"A lightweight key/value json storage with persistence.","archived":false,"fork":false,"pushed_at":"2022-02-12T09:37:28.000Z","size":594,"stargazers_count":57,"open_issues_count":7,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-16T18:00:29.818Z","etag":null,"topics":["database","json","key-value","lodash","storage"],"latest_commit_sha":null,"homepage":"https://trivialsoftware.github.io/trivialdb","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/trivialsoftware.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"issuehunt":"morgul","custom":"https://www.paypal.me/morgul"}},"created_at":"2014-05-09T01:48:05.000Z","updated_at":"2024-10-13T11:19:17.000Z","dependencies_parsed_at":"2022-08-25T19:10:35.796Z","dependency_job_id":null,"html_url":"https://github.com/trivialsoftware/trivialdb","commit_stats":null,"previous_names":["morgul/jbase","morgul/trivialdb"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/trivialsoftware/trivialdb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivialsoftware%2Ftrivialdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivialsoftware%2Ftrivialdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivialsoftware%2Ftrivialdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivialsoftware%2Ftrivialdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trivialsoftware","download_url":"https://codeload.github.com/trivialsoftware/trivialdb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivialsoftware%2Ftrivialdb/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266483779,"owners_count":23936418,"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","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","json","key-value","lodash","storage"],"created_at":"2024-08-09T13:02:06.961Z","updated_at":"2025-07-22T11:31:50.805Z","avatar_url":"https://github.com/trivialsoftware.png","language":"JavaScript","funding_links":["https://issuehunt.io/r/morgul","https://www.paypal.me/morgul","https://paypal.me/morgul/5"],"categories":["JavaScript"],"sub_categories":[],"readme":"# TrivialDB\n\n[![Build Status](https://img.shields.io/travis/trivialsoftware/trivialdb/master.svg)](https://travis-ci.org/trivialsoftware/trivialdb)\n[![npm Version](https://img.shields.io/npm/v/trivialdb.svg)](https://www.npmjs.com/package/trivialdb)\n![npm](https://img.shields.io/npm/dm/trivialdb.svg)\n[![GitHub issues](https://img.shields.io/github/issues/trivialsoftware/trivialdb.svg)](https://github.com/trivialsoftware/trivialdb/issues)\n[![Donate $5](https://img.shields.io/badge/Donate-%245-yellow.svg)](https://paypal.me/morgul/5)\n\nTrivialDB is a lightweight key/value json storage with persistence. Conceptually, it's just a thin lodash wrapper around\nplain javascript objects; with the added bonus of doing versioned asynchronous writes on changes. Its on disk format is \nsimply \"json on disk\"; basically the json version of the plain object, saved to a file on disk. This makes making hand \nedits not just possible, but simple.\n\n## Use Case\n\nTrivialDB is intended for simple storage needs. It's in-process, small, and very, _very_ fast. It takes almost nothing \nto get up and running with it, and it gives you an impressive amount of power, thanks to [lodash chaining][]. I've found \nits a great fit for any personal project that needs to persist data. If you find yourself wanting to work with raw json \nfiles, it's a rather large improvement on writing your own loading/saving/querying logic. \n\nThe 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=\u003csize\u003e`.) 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.\n\nIn fact, the very popular nosql database [Redis][redis] is in-memory. In their FAQ, they have this to say:\n\n\u003e In the past the Redis developers experimented with Virtual Memory and other systems in order to allow larger than RAM \ndatasets, but after all we are very happy if we can do one thing well: data served from memory, disk used for storage. \nSo for now there are no plans to create an on disk backend for Redis. Most of what Redis is, after all, is a direct \nresult of its current design.\n\nIn practice, I use TrivialDB to power a wiki that has thousands of printed pages worth of text, and the node process \nuses around 200mb, with the json being around 1mb on disk. For things like a blog, or user database, or session storage,\nor a preference system, TrivialDB will work for a long time before you need to move to something out of process.\n\nThe one caveat to keep in mind is this: _every database you work with is stored in memory_. Since TrivialDB is \nin-process, you might run into the memory limits of node; (on versions before 0.12 there's a 1.4GB - 1.7GB limit). \nHowever, this isn't actually that much of a limitation. Generally, you're working with a large amount of your \ndata in memory anyway; your data sets can get relatively large before you even need to worry about this.\n\n[redis]: https://redis.io\n[lodash chaining]: https://lodash.com/docs#lodash\n\n### In-Browser Database\n\nOne of the new and exciting use cases is that TrivialDB is now usable inside a browser! By default it will read/write\nJSON over REST, but you can easily change this to use IndexedDB or LocalStorage. You can even use a bundler like\nBrowserify or Webpack to include the JSON directly, and have zero load time.\n\nThis helps when developing static, \"server-less\" sites; you can have a development version that generates the JSON \nlocally, commit it to git, and then have your static site generation simply include the new JSON files and push them \nout. Your client-side code can still work with TrivialDB as if it was a normal application.\n\n(For more information, please see the [\"Reading and Writing in a Browser\"](#reading-and-writing-in-a-browser) section.)\n\n## Lodash Shoutout\n\nThis entire project is made possible by the [lodash][] project. If it wasn't for their hard work and the effort they put \ninto building an amazing API, TrivialDB would not exist.\n\n[lodash]: https://lodash.com\n\n## Installation\n\nSimply install with npm:\n\n```bash\n$ npm install --save trivialdb\n```\n\n## TrivialDB API\n\nThere are two concepts to remember with TrivialDB: namespaces and databases. A 'namespace' is, as it implies, just an\nisolated environment with a name. Inside a namespace, all _database_ names must be unique. So, if you want to have to \nindependent 'foobar' databases, you will need to have them in different namespaces.\n\nDatabases, on the other hand, are the heart and soul of TrivialDB. As the name implies, they hold all your data. \nDatabase objects are the interesting ones, with the main API you will be working with in TrivialDB.\n\n### Creating a namespace\n\n* `ns(name, options)` - creates or retrieves a `TDBNamespace` object.\n\t* _alias: 'namespace'_\n\t\t\n```javascript\nconst trivialdb = require('trivialdb');\n\n// Create a namespace\nconst ns1 = trivialdb.ns('test-ns');\n\n// Create a namespace with some options\nconst ns2 = trivialdb.ns('test-ns', { dbPath: 'server/db' });\n\n// Create a database inside that namespace\nconst db = ns1.db('test', { writeToDisk: false });\n```\n\nOnce you've created your namespace object, you can create or retrieve database instances from it, just like you can the \nmain TrivialDB module.\n\n##### Options\n\nThe options supported by the `ns` call are:\n\n```javascript\n{\n    basePath: \"...\",\t// The base path for all other paths to be relative to. (Defaults to the application's base directory.)\n    dbPath: \"...\"\t// The path, relative to `basePath` to the root database folder. (Defaults to 'db'.)\n}\n```\n\nIf you call `ns` passing in the name of an existing namespace, any options passed will be ignored.\n\n### Creating a database\n\n* `db(name, options)` - creates or retrieves a database instance.\n\t* _alias: 'database'_\n\n```javascript\nconst trivialdb = require('trivialdb');\n\n// Open or create a database\nconst db = trivialdb.db('some_db');\n\n// Open or create a database, with options\nconst db2 = trivialdb.db('some_db2', { writeToDisk: false });\n```\n\nBy default, when a new database is created, it will look for a file named `'some_db.json'` inside the database folder.\n(By default this is `'\u003capplication\u003e/db'`. You can control this path by setting the `basePath` or `dbPath` options of the \nnamespace, or alternatively, the `dbPath` or `rootPath` options of the database.)\n\nYou can request the same database multiple times, and get back the same instance (though any options passed on \nsubsequent calls will be ignored). This allows you to request the database by name in different places in your code, \nand not worry about the two database instance fighting with each other.\n\n##### Options\n\nThe options supported by the `db` call are:\n\n```javascript\n{\n    writeToDisk: true || false,  // Whether or not to persist the database to disk. (Default: `true`)\n    loadFromDisk: true || false, // Whether or not to read the database in from disk on load. (Default: `true`)\n    rootPath: \"...\",            // The path to a folder that will contain the persisted database json files. (Default: './')\n    dbPath: \"...\",\t\t// The path, relative to the namespace's `basePath` to the root database folder. (Defaults to 'db'.)\n    writeDelay: ...,            // A number in milliseconds to wait between writes to the disk. (Default: 0)\n    prettyPrint: true || false,  // Whether or not the json on disk should be pretty printed. (Default: `true`)\n    pk: \"...\",                  // The field in the object to use as the primary key. (Default: `undefined`)\n    idFunc: function(){...}     // The function to use to generate unique ids.\n}\n```\n\nIf you call `db` passing in the name of an existing namespace, any options passed will be ignored.\n\n## Namespace API\n\nNamespaces have exactly one function, `db`, which works exactly like the TrivialDB function for creating a database.\n(see above.)\n\n## Database API\n\nTrivialDB database objects have two APIs, one synchronous, the other asynchronous (Promise based). The synchronous API\nis significantly faster, but it does not trigger syncing to disk, and should be considered a 'dirty' form of reading and \nwriting. In the future, TrivialDB may get the ability to support multiple processes sharing the same file, and at that \ntime, the synchronous API will be a truly dirty API, with the values often being out of date. (See the more in depth\ndiscussion in each relevant section below.)\n\n### Properties\n\nThe database object has the following properties:\n\n* `name` - The name given to the database. (Also the filename, minus extension.)\n* `count` - The number of keys in the database.\n* `path` - The full path to the backing file, assuming it writes to disk.\n* `rootPath` - The full path to the folder for the database (aka `path` minus the filename).\n* `loading` - A promise that is resolved once the initial data is loaded.\n\n### Database Options\n\nThere are some options that deserve further details.\n\n#### Custom ID Generation\n\nIf you want to generate your own ids, and not use the ids TrivialDB generates by default, you can specify your own\nfunction in the database options. By specifying `idFunc`, TrivialDB will use this function to generate all ids, when needed.\nThe `idFunc` function is passed the object, so you can generate ids based on the object's content, if you wish. (An\nexample of this would be generating a slug from an article's name.)\n\n```javascript\nfunction slugify(article)\n{\n    return article.name.toString().toLowerCase()\n        .replace(/\\s+/g, '-')\n        .replace(/[^\\w\\-]+/g, '')\n        .replace(/\\-\\-+/g, '-')\n        .replace(/^-+/, '')\n        .replace(/-+$/, '');\n} // end slugify\n\n// Declare a new database, using the slugify function above.\nconst db = trivialdb.db(\"articles\", { writeToDisk: false, idFunc: slugify });\n\n// Now, we save an object\ndb.save({ name: \"TrivialDB: now with id generation functions!\", body: \"Read the title, dude.\" })\n    .then(function(id)\n    {\n        // This prints the id: 'trivialdb-now-with-id-generation-functions'.\n        console.log('id:', id);\n    });\n```\n\nBe careful; it is up to you to ensure your generated ids are unique. Additionally, if your generation function blows up,\nTrivialDB may return some nonsensical errors. (This may improve in the future.)\n\n#### `readFunc` and `writeFunc`\n\nYou can override the built in underlying read and/or write functions. By default these will read/write from the disk (in node) or `GET`/`POST` to the specified path in the browser. You can, however, override them with any `Promise` returning function.\n\n* `readFunc(path)` - This function is passed the absolute path of the file as `path`. The `rootDir` will be `/` on \nbrowser, or the root directory of the running node process. This function _must_ return a `Promise`. The promise's \nreturn value is ignored.\n* `writeFunc(path, jsonStr)` - This function is passed the absolute path of the file as `path`, and the json string\nrepresentation of the database as `jsonStr`. The `rootDir` will be `/` on browser, or the root directory of the running \nnode process. This function _must_ return a `Promise`. The promise's return value is ignored.\n\n### Loading\n\nAs long as `loadFromDisk` (or `writeToDisk`) is not set to false, TrivialDB will attempt to load a database when you \nfirst call `.db()`. Sometimes, you need to wait for the datbase to be loaded before doing operations. This is why we \nprovide a `loading` promise on the db object. Waiting for the database to be done is very simple:\n\n```javascript\n// This could declare a new DB, or it could be pulling an existing one from the cache.\nconst db = trivialdb.db(\"articles\");\n\n// This will execute once the db is loaded. If it is already loaded, we resolve instantly.\ndb.loading.then(() =\u003e\n    {\n        console.log('loaded.');\n    });\n```\n\nIt's worth mentioning that the `loading` promise is always available, even if disk operations will not be performed.\nThis means you can always wait on the `loading` promise, without knowing details about how the database is configured.\n\n#### `loaded` event\n\nIf you don't want to use the loading promise, there is also a `loaded` event that is always fired off once the database\nhas finished loading. This event does still fire if there's no disk operations to do.\n\n```javascript\n// This could declare a new DB, or it could be pulling an existing one from the cache.\nconst db = trivialdb.db(\"articles\");\n\n// This will execute once the db is loaded. If it is already loaded, **this will never fire.**\ndb.on('loading', () =\u003e\n    {\n        console.log('loaded.');\n    });\n```\n\n_Note: Due to the nature of events, if the database has already loaded, listening for the `loaded` event will never \ntrigger. There is no way to know, other than to call `db.loading.isPending()`, at which point you should probably just \nuse the promise directly._\n\n#### Reading and Writing in a Browser\n\nBy default, in node, TrivialDB will attempt to read and write using the `fs` library. The path will be relative to the\nproject's absolute path. However, in a browser, we can't use `fs`. So, instead, we use the [fetch][] api to make REST\ncalls. The `path` is relative to `/`, and will look something like `/db/namespace/some_db.json`.\n\nFor loading the database, it will make a `GET` request, and for writing, it will make a `POST` request. If you need to\ndo something different, like using `PUT` or maybe transmitting data over websockets, simply override the `readFunc`\nand/or `writeFunc` options in the configuration. \n\n[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API\n\n### Key/Value API\n\nThe synchronous API follows a scheme of `get`, `set`, `del`. Primarily, these functions work with the internal memory store \ndirectly, meaning that in the case of `set` or `del`, thier changes will not be persisted until something else triggers\na write to disk. If you have set `writeToDisk` to `false`, then you can use these APIs without any concern at all.\n\nThe asynchronous API follows a scheme of `load`, `save`, `remove`. These functions are always considered safe; they will\nnot resolve their promises until after the changes have been successfully saved to disk. (They will, however, modify the\ndata immediately, so dirty reads/writes may occur while the safe read/write is pending, and it will get the updated \nvalue.)\n\nIt should be noted that currently, `get` and `load` are only differentiated by the fact that `load` returns a promise. \nIn the future, `load` may be modified to sync from disk, allowing for multiple processes to write to the same json file.\nThis is important to keep in mind, as `get` is a very popular function, if you are in a multiprocess scenario in the \nfuture, it may return stale values. As such, it should be considered a dirty read.\n\n#### Retrieving Values\n\n* Synchronous\n\t* `get(key, defaultVal)` - Returns the value stored under `key`or `undefined`.\n* Asynchronous\n\t* `load(key)` - Returns a promise resolved to the value or throws `DocumentNotFoundError`.\n\t\n```javascript\n// Get an object synchronously\nconst val = db.get('my_key');\n\n// Get an object synchronously, with a default value\nconst val2 = db.get('does_not_exist', 'default');\n\n// Get an object asynchronously\ndb.load('my_key')\n    .then(function(val)\n    {\n        // Work with `val` here\n    });\n\n// Get an object asynchronously, with a default value\ndb.load('does_not_exist', 'default')\n    .then(function(val)\n    {\n    \t// val is equal to 'default'\n    });\n\n// Get an object asynchronously that doesn't exist\ndb.load('does_not_exist')\n    .then(function(val)\n    {\n    \t// Will never get here\n    })\n    .catch(trivialdb.errors.DocumentNotFound, function(error)\n    {\n        // Handle the error.\n    });\n```\n\nTrivialDB only supports direct retrieval by a single string identifier. If a value for that key is not found, `undefined`\nwill be returned for `get` (This mirrors the direct use of objects in JavaScript); additionally, we allow you to pass in\na default value, which will be returned if the key is not found. This is _not_ supported on `load`, however, as `load` \nis intended to return you _exactly_ what is in the database at this moment. If you attempt to use `load` to get a \ndocument that does not exist, it will throw a `DocumentNotFoundError` object. This allows you to do traditional promise\nerror handling, as opposed to using `if(result === undefiend)`.\n\n#### Storing Values\n\n* Synchronous\n    * `set(value)` - Returns a generated key.\n    * `set(key, value)` - Returns `key`.\n* Asynchronous\n    * `save(value)` - Returns a promise resolved with a generated key.\n    * `save(key, value)` - Returns a promise resolved with `key`.\n\n```javascript\n// Store a value\nconst id = db.set({ name: 'foo' });\n\n// Store a value with a specific key\ndb.set('foo', { name: 'foo' });\n\n// Overwrite the previous value\ndb.set('foo', { name: 'bar' });\n\n// Asynchronously store a value\ndb.save({ name: 'foo' })\n\t.then(function(id)\n\t{\n\t\t// Work with 'id' here.\n\t});\n```\n\nAll values in TrivialDB are stored under a key. They _may_ be objects, or primitive types. If you do not pass in a key, \nTrivialDB will generate one for you. (The autogenerated keys are base62 encoded uuids, basically the same algorithm use \nby url shorteners.) In the event you do not pass a key, your will need to look at the return value to know how to \nretrieve your objects.\n\nIf you specify a key, it is up to you to ensure it's unique. TrivialDB will silently overwrite any previous value.\n\nTrivialDb supports the `pk` option for setting a primary key. Keys are **always added if your value is an object**, but\n with the `pk` options, you can control what field it is stored under. (By default, it's `id`.)\n\n#### Removing Values\n\n* Synchronous\n    * `del(predicate)` - Returns a list of removed values.\n* Asynchronous\n    * `remove(predicate)` - Returns a promise resolved with a list of removed values.\n\nRemoving values works off a lodash predicate, must like [filter][]. This allows for removing multiple documents at the \nsame time. However, if you only wish to remove one, you will need to pass in an object that selects your primary key, \nfor example:`{ id: 'my_key' }`.\n\n[filter]: https://lodash.com/docs#filter\n\n##### Deleting the database\n\n* `clear()` - Returns a promise resolved once the database is considered 'settled'.\n\nIn addition to removing an individual key, you can clear the entire database. This **always** syncs to disk.\n\n### Query API\n\nInstead of exposing a large, complex Query API, TrivialDB exposes [lodash chain][] objects, allowing you to perform \nlodash queries to filter and manipulate your data in any way you want. As this uses lazy evaluation, it's fast and \nefficient even on large datasets.\n\n_Note: TrivialDB currently uses **explicit** chaining, meaning that you must always use `.run()`/`.value()`. Please \ncheck the [docs](https://lodash.com/docs/#lodash) to understand the full implications of this._\n\n#### Basic Filtering\n\n* `filter(predicate)` - Returns the values that match the predicate.\n\n```javascript\n// Simple object filter\nconst vals = db.filter({ foo: 'bar!' });\n\n// Function filter\nconst vals2 = db.filter(function(value, key)\n{\n    // Decide if you want this object\n    return value.foo === 'bar!';\n});\n```\n\nTrivialDB has a simple filter function for when you just want a lodash [filter][]. It works as you would expect, \nfiltering all items in the database by the predicate you passed in.\n\n[filter]: https://lodash.com/docs#filter\n\n#### Advanced Queries\n\n* `query()` - Returns a [lodash chain][] object, wrapped around all values in the database.\n\n```javascript\n// Query for all admins, sorting by created date\nconst items = db.query()\n\t.filter({ admin: true })\n\t.sortBy('date')\n\t.run();\n\n// Find the most recently created user\nconst latestUser = db.query()\n\t.sortBy('date')\n\t.last()\n\t.run();\n```\n\nThis exposes a [lodash chain][] object, which allows you to run whatever lodash queries you want. It clones the \ndatabase's values, so feel free to make any modifications you desire; you will not affect the data in the database.\n\n_Note:_ As you can see from our example, we execute the query with `.run()`. This alias was removed in Lodash 4. We\njump through a few hoops to extend the prototype of the individual chain object to add this back in there; this should\nnot leak into the global lodash module. Why did we do this? Because I like the semantics of `.run()`, dammit.\n\n[lodash chain]: https://lodash.com/docs#chain\n\n### Reload\n\n* `reload()` - Returns a promise resolved once the database has been reloaded from disk.\n\nIf you need to reload your database for any reason (such as hand-edited JSON files), you can reload the database from\ndisk with the `reload()` function. This is the same function that is used to load from disk initially.\n\nThis function resets the `loading` promise, and emits a `loaded` event once complete.\n\n_Note:_ This will throw an exception on any database with `loadFromDisk: false`.\n\n_Note:_ This will completely throw away all values from in memory. If saving is not settled, changes may be lost.\n\n### Direct Access\n\n* `sync()` - Returns a promise resolved once the database is considered 'settled'.\n\nYou can directly access the key/value store with the `values` property on the database instance. This is exposed\nexplicitly to allow you as much freedom to work with your data as you might want. However, TrivialDB can't detect any\nchanges you make directly, so you will need to call the `sync` function to get your changes to persist to disk.\n\n```javascript\n// Add a new key manually\ndb.values['foobar'] = { test: \"something\" };\n\n// Sync that new key to disk\ndb.sync();\n```\n\nThe `sync` function returns a promise that is resolved once the database has 'settled', as in, there are no more\nscheduled writes. Because of this behavior, you should consider whether or not you want to wait on its promise. Under\nhigh load, (or with a high `writeDelay`) it's possible for a `sync` promise's resolution to be considerably delayed.\n\n```javascript\n// Add a new key manually\ndb.values['foobar'] = { test: \"something\" };\n\n// Sync that new key to disk\ndb.sync()\n    .then(function()\n    {\n        // Sync is done, db is settled\n    });\n```\n\nAlso, you should feel free to iterate over the values object if you need to do any advanced filtering. All the same\ncaveats of working with a plain javascript object apply. Just remember to call `sync` if you've made any modifications.\n\n## Status\n\nWith the release of v2.0.0, v1.x is no longer supported. Additionally, there were large, breaking API changes.\n\nTrivialDB is **stable and production ready** (for the intended use case). I will provide support for v2.x for the \nforeseeable future. I will even attempt to help with v1.x if you're using it in a production product, but I can't make \nany promises.\n\nIf you are using this in a production product, please get in touch. Not only would I love to know, but if you need \ndirect support, I'd be more than willing to discuss it.\n\n### Updates\n\nSince the code base is small enough, it's relatively immune to the most common forms of 'code rot'. I make improvements \nwhen they're needed, or if someone files an issue. Just because I haven't touched it in a year or two doesn't mean it's \ndead; if you're concerned, feel free to file an issue and ask if it's still being supported.\n\n## Contributing\n\nWhile I only work on TrivialDB in my spare time (what little there is), I use it for several of my projects. I'm more than\nhappy to accept merge requests, and/or any issues filed. If you want to fork it and improve part of the API, I'm ok with\nthat too, however I ask you open an issue to discuss your proposed changes _first_. And, since it's MIT licensed, you\ncan of course take the code and use it in your own projects.\n\n## Donations\n\n[![Donate $5](https://img.shields.io/badge/Donate-%245-yellow.svg)](https://paypal.me/morgul/5)\n\nI accept donations for my work. While this is not my primary means of income, by any stretch, I would not mind a \nfew bucks if you find the software useful. \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrivialsoftware%2Ftrivialdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrivialsoftware%2Ftrivialdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrivialsoftware%2Ftrivialdb/lists"}