Murmuration
raw JSON → 2.0.80 verified Sat May 09 auth: no javascript
Murmuration is a low-level database library providing statement generation, transactions, and migrations. It serves as a lightweight alternative to ORMs like Sequelize or TypeORM, focusing on minimal, dynamic query building with a promise-like syntax. The base package (v2.0.80) is abstract and intended to be extended by specific implementations: Murmuration-MariaDB and Murmuration-PostGreSQL. Key differentiators include its use of operations to wrap transactions and its built-in migration support that synchronizes the database schema during deployment. It deliberately avoids abstractions like models or query builders, giving developers direct control over SQL.
Common errors
error Cannot find module 'murmuration' ↓
cause The package is not installed, or you are trying to use the base package without installing a database-specific implementation.
fix
Run
npm install murmuration-mariadb or npm install murmuration-postgresql and import from that package instead. error TypeError: using is not a function ↓
cause You are trying to use require('murmuration') directly as a function, but the package exports an object with named exports, not a function.
fix
Define a local
using function by extending the Statement class. Example: const { Statement } = require('murmuration'); const using = (connection) => new Statement(connection); error TypeError: Cannot read properties of undefined (reading 'selectFromAccount') ↓
cause The using() function is not properly set up with database-specific methods like selectFromAccount(). The base murmurration does not include these.
fix
Create a using function that extends Statement with your database schema's methods, or use a package like murmuration-mariadb that provides them.
Warnings
breaking Version 2.x changed the API from callback-based to promise-like chaining. Old .end() method replaced with .execute(). ↓
fix Replace .end() with .execute() on statement chains.
breaking Version 2.0 removed the default export; require('murmuration') no longer returns a constructor. Use named exports like { Statement } or { migrate }. ↓
fix Change const Murmuration = require('murmuration') to const { Statement } = require('murmuration').
deprecated The base Murmuration package is deprecated; use Murmuration-MariaDB or Murmuration-PostGreSQL instead. ↓
fix Install the appropriate database-specific package: npm install murmuration-mariadb or npm install murmuration-postgresql.
gotcha The using() function must be defined locally; the package does not export it directly. It is typically created by extending the Statement class with database-specific connection methods. ↓
fix Create a using.js file that imports and extends Statement with your database driver's execute method.
gotcha The where() method only supports equality conditions (simple object). For operators like IN, LIKE, or OR, you must write raw SQL and use a different approach. ↓
fix Use a raw query method or extend Statement to support custom conditions.
breaking Migration schema changed: migration files must export an object with up and down functions instead of arrays of SQL strings. ↓
fix Refactor migration files to export { up: async (connection) => { ... }, down: async (connection) => { ... } }.
Install
npm install murmuration yarn add murmuration pnpm add murmuration Imports
- using wrong
import using from 'murmuration';correctconst using = require('murmuration'); - Statement wrong
const Statement = require('murmuration').Statement;correctconst { Statement } = require('murmuration'); - migrate wrong
import { migrate } from 'murmuration';correctconst { migrate } = require('murmuration');
Quickstart
const { Statement, migrate } = require('murmuration');
const withConnection = (connection) => ({
selectFromUsers: () => ({
where: (conditions) => ({
one: (handler) => ({ else: (elseHandler) => ({ catch: (errHandler) => ({ execute: async () => {
const sql = `SELECT * FROM users WHERE ${Object.keys(conditions).map(k => `${k} = ?`).join(' AND ')}`;
const values = Object.values(conditions);
try {
const rows = await connection.execute(sql, values);
if (rows.length === 1) handler(rows[0]);
else elseHandler();
} catch (err) { errHandler(err); }
}})
})
})
});
const using = (connection) => withConnection(connection);
async function quickstart() {
const connection = { execute: async (sql, params) => [[{ id: 1, name: 'Alice' }], []] };
const context = { emailAddress: 'alice@example.com', password: 'secret' };
using(connection)
.selectFromUsers()
.where({ emailAddress: context.emailAddress, password: context.password })
.one(({ id }) => { console.log('Found user:', id); })
.else(() => { console.log('User not found'); })
.catch((err) => { console.error('Error:', err); })
.execute();
}
quickstart();