{"id":40865,"library":"dulcimer","title":"Dulcimer","description":"An ORM for embedded keystores in Node.js, providing a consistent API for developing with LevelDB and deploying with Riak. Version 2.8.4 is stable but development has largely halted; last updated in 2017. Notable features include models, indexes, foreign keys, derived fields, validation, and pagination. Unlike traditional SQL ORMs, Dulcimer is designed for key-value stores with limited querying capabilities. Backends: LevelDB (default) and Riak; Redis support was planned but never completed.","status":"maintenance","version":"2.8.4","language":"javascript","source_language":"en","source_url":"git@github.com:fritzy/Dulcimer","tags":["javascript"],"install":[{"cmd":"npm install dulcimer","lang":"bash","label":"npm"},{"cmd":"yarn add dulcimer","lang":"bash","label":"yarn"},{"cmd":"pnpm add dulcimer","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Default backend for development and testing","package":"level","optional":true},{"reason":"Optional Riak backend for production","package":"riak-js","optional":true},{"reason":"Underlying model definition library","package":"verymodel","optional":false}],"imports":[{"note":"Dulcimer does not support ESM imports; use CommonJS require.","wrong":"import dulcimer from 'dulcimer'","symbol":"dulcimer","correct":"const dulcimer = require('dulcimer')"},{"note":"Model is a constructor, not a factory. Use 'new dulcimer.Model()'.","wrong":"const Person = dulcimer.Model.create({...})","symbol":"Model","correct":"const Person = new dulcimer.Model({...}, {name: 'person'})"},{"note":"For LevelDB, a string path is accepted; object form is also valid but string is simpler.","wrong":"dulcimer.connect({type: 'level', path: './test.db'})","symbol":"connect","correct":"dulcimer.connect('./test.db')"}],"quickstart":{"code":"const dulcimer = require('dulcimer');\ndulcimer.connect('./test.db');\n\nconst Person = new dulcimer.Model({\n  firstName: {},\n  lastName: {},\n  fullName: {\n    derive: function () {\n      return this.firstName + ' ' + this.lastName;\n    }\n  }\n}, {name: 'person'});\n\nconst nathan = Person.create({\n  firstName: 'Nathan',\n  lastName: 'Fritz'\n});\nnathan.save(function (err) {\n  if (err) console.error(err);\n  Person.all(function (err, persons) {\n    if (err) console.error(err);\n    persons.forEach(function (person) {\n      console.log(person.toJSON());\n    });\n  });\n});","lang":"javascript","description":"Initialize a LevelDB store, define a Person model with a derived field, create and save an instance, then retrieve all records."},"warnings":[{"fix":"Call dulcimer.connect() immediately after require.","message":"connect() must be called before using any model methods; otherwise operations will fail silently.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Specify keyType: 'number' in model options or ensure keys are strings.","message":"Model keys are strings by default; if you use numeric keys, set keyType to 'number' in model options.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Replace offset with continuation parameter in query options.","message":"The 'offset' option in queries is deprecated; use 'continuation' for pagination instead.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Use {depth: 1} option in queries or manually call the foreign key getter.","message":"Foreign keys (foreignKey) do not automatically load related objects unless depth is set.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Always specify a limit and use continuation for pagination.","message":"all() without options returns all objects; for large datasets use limit and continuation.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Install riak-js@0.9.x explicitly.","message":"The Riak backend requires riak-js version 0.9.x; newer versions are not compatible.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"search_vec":"'2.8.4':22 '2017':33 'api':12 'backend':62 'capabl':61 'complet':73 'consist':11 'default':64 'deploy':18 'deriv':41 'design':52 'develop':14,26 'dulcim':1,50 'embed':5 'featur':35 'field':42 'foreign':39 'halt':29 'includ':36 'index':38 'javascript':74 'key':40,55 'key-valu':54 'keystor':6 'larg':28 'last':30 'leveldb':16,63 'limit':59 'model':37 'never':72 'node.js':8 'notabl':34 'orm':3,49 'pagin':45 'plan':70 'provid':9 'queri':60 'redi':67 'riak':20,66 'sql':48 'stabl':24 'store':57 'support':68 'tradit':47 'unlik':46 'updat':31 'valid':43 'valu':56 'version':21","created_at":"2026-06-04T18:49:38.032948+00:00","updated_at":"2026-06-04T18:49:38.032948+00:00","problems":[{"fix":"Use const dulcimer = require('dulcimer'); after npm install dulcimer.","cause":"Importing dulcimer incorrectly (e.g., using ESM import) or require() from a relative path that points to a different export.","error":"TypeError: dulcimer.connect is not a function"},{"fix":"Add {name: 'modelname'} as second parameter to new dulcimer.Model().","cause":"Model definition missing the 'name' option in the second argument.","error":"Error: Model must have a name"},{"fix":"Call dulcimer.connect() immediately after requiring the module.","cause":"dulcimer.connect() was not called before performing database operations.","error":"Error: No database connected"},{"fix":"Ensure the object is saved first and the key matches exactly (case-sensitive).","cause":"Trying to get or delete a model instance that hasn't been saved or has a different key.","error":"Error: Key not found"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/fritzy/Dulcimer","github":"git@github.com:fritzy/Dulcimer","docs":null,"changelog":null,"pypi":null,"npm":"dulcimer","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-04","next_check":"2026-09-02","install_tag":null}}