{"id":16542,"library":"ssb-db2","title":"SSB-DB2","description":"SSB-DB2 is a new database for secure-scuttlebutt, designed as a replacement for the older `ssb-db`. Currently at version 8.1.0, it offers significant architectural changes aimed at improving performance and flexibility. Key differentiators include using `bipf` for data storage, replacing `flume` with `jitdb` for specialized indexes, supporting browser environments via `ssb-browser-core`, and enabling efficient partial replication. It has expanded capabilities beyond `ssb-db`, featuring deletion and compaction, support for customizable feed and encryption formats (defaulting to `ssb-classic`), and a powerful query language based on composable JavaScript functions. SSB-DB2 operates as a `secret-stack` plugin, registering within the `db` namespace, and is optimized for modern Node.js environments (>=16).","status":"active","version":"8.1.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/ssb-ngi-pointer/ssb-db2","tags":["javascript"],"install":[{"cmd":"npm install ssb-db2","lang":"bash","label":"npm"},{"cmd":"yarn add ssb-db2","lang":"bash","label":"yarn"},{"cmd":"pnpm add ssb-db2","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"SSB-DB2 is designed as a secret-stack plugin and requires it for integration into an SSB peer.","package":"secret-stack","optional":false},{"reason":"Required for `secret-stack` configuration, specifically for the `appKey`.","package":"ssb-caps","optional":false}],"imports":[{"note":"While the documentation examples use `require`, SecretStack supports ESM import. This is the primary entry point for building an SSB peer.","wrong":"const SecretStack = require('secret-stack')","symbol":"SecretStack","correct":"import SecretStack from 'secret-stack'"},{"note":"SSB-DB2 is typically imported as a SecretStack plugin. When used with `secret-stack`, it is loaded via `.use(require('ssb-db2'))` in CJS or via dynamic import in ESM if `secret-stack` supports it.","wrong":"import { ssbdb2 } from 'ssb-db2'","symbol":"ssb-db2","correct":"import ssbdb2 from 'ssb-db2'"},{"note":"Query operators are imported as named exports from a dedicated `operators` submodule. Direct `require('ssb-db2')` will not expose these.","wrong":"const { where, and, type, author, toCallback } = require('ssb-db2')","symbol":"{ where, and, type, author, toCallback }","correct":"import { where, and, type, author, toCallback } from 'ssb-db2/operators'"}],"quickstart":{"code":"const SecretStack = require('secret-stack')\nconst caps = require('ssb-caps')\nconst fs = require('fs')\nconst path = require('path')\n\nconst testPath = './temp-ssb-db2-quickstart'\n\n// Ensure a clean state for the quickstart\nif (fs.existsSync(testPath)) {\n  fs.rmSync(testPath, { recursive: true, force: true });\n}\nfs.mkdirSync(testPath, { recursive: true });\n\nconst sbot = SecretStack({ caps })\n  .use(require('ssb-db2'))\n  .call(null, { path: testPath })\n\nsbot.db.create({ content: { type: 'post', text: 'hello from ssb-db2!' } }, (err, msg) => {\n  if (err) {\n    console.error('Error publishing message:', err);\n    sbot.close()\n    return;\n  }\n  console.log('Published message:', msg.value.content);\n\n  const { where, type, toCallback } = require('ssb-db2/operators');\n  sbot.db.query(\n    where(type('post')),\n    toCallback((err, msgs) => {\n      if (err) {\n        console.error('Error querying messages:', err);\n      } else {\n        console.log('Found ' + msgs.length + ' post messages:');\n        msgs.forEach(m => console.log('- ' + m.value.content.text));\n      }\n      sbot.close();\n      fs.rmSync(testPath, { recursive: true, force: true }); // Clean up\n    })\n  );\n});","lang":"javascript","description":"This quickstart demonstrates how to set up an SSB peer with ssb-db2, publish a message, and then query for 'post' messages using the new query operators."},"warnings":[{"fix":"Review the 'Migrating from ssb-db' and 'Preventing forking feeds' sections in the `ssb-db2` documentation. For writing to the new log, ensure the old log is fully migrated and deleted, potentially using `config.dangerouslyKillFlumeWhenMigrated`.","message":"SSB-DB2 is a replacement for `ssb-db` and is *not* 100% backwards compatible. It uses a different underlying log format (`bipf` instead of `flume`) and requires a migration process if you intend to query existing `ssb-db` data. Attempting to use write APIs on `ssb-db2` while an old log exists and is being migrated can lead to inconsistent states or 'forking feeds'.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Upgrade your Node.js environment to version 16 or newer. Use a tool like `nvm` to manage Node.js versions.","message":"SSB-DB2 explicitly requires Node.js version 16 or higher. Older Node.js versions are not supported and will likely result in runtime errors.","severity":"breaking","affected_versions":"<16"},{"fix":"Consult the `ssb-db2` documentation on 'Leveldb plugins' to understand which plugins are needed for specific query types (e.g., `ssb-db2/full-mentions`). Integrate these plugins into your `secret-stack` configuration.","message":"Some advanced queries require additional LevelDB index plugins, as the default `jitdb` (Just-In-Time Database) indexing only covers basic functionality. Queries relying on specific data patterns not covered by the base index will not return expected results.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When migrating or using both, utilize `ssb-db2/compat` if you need to run both `ssb-db` and `ssb-db2` simultaneously, or ensure you've fully transitioned to `ssb-db2` as the primary database.","message":"SSB-DB2 registers itself in the `db` namespace of a `secret-stack` instance. If `ssb-db` (or another plugin also registering in `db`) is used concurrently without proper compatibility layers, it can lead to conflicts or unexpected behavior.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure `sbot.use(require('ssb-db2'))` is called on your `secret-stack` instance before `sbot.call(null, config)`.","cause":"The `ssb-db2` plugin was not correctly registered with the `secret-stack` instance.","error":"Error: method:db.create is not in list of allowed methods."},{"fix":"Verify that `secret-stack` is initialized with `caps` and that `ssb-db2` is correctly added as a plugin before attempting to access `sbot.db`.","cause":"The `db` namespace, where `ssb-db2` registers its API, is undefined, typically because `ssb-db2` failed to load or `secret-stack` was not properly initialized.","error":"TypeError: Cannot read properties of undefined (reading 'query')"},{"fix":"Convert your imports to ESM syntax (e.g., `import SecretStack from 'secret-stack'`) or ensure your files are treated as CommonJS modules.","cause":"Attempting to use CommonJS `require` syntax in an ESM module context (e.g., a file with `\"type\": \"module\"` in `package.json` or a `.mjs` file).","error":"ReferenceError: require is not defined"},{"fix":"Double-check the spelling of the operator. Ensure all query operators are imported specifically from `ssb-db2/operators`, e.g., `const { where, type } = require('ssb-db2/operators')`.","cause":"Attempting to use a non-existent or misspelled query operator, or trying to import operators from the wrong path.","error":"Error: Unknown operator 'foo'"}],"ecosystem":"npm"}