{"id":18589,"library":"najm-database","title":"Najm Database Plugin","description":"Community-maintained database plugin for the Najm API framework (v1.1.8). Provides decorator-based transaction management, automatic rollback, Drizzle ORM integration, and Zod schema validation. Requires najm-core, reflect-metadata, drizzle-orm >=0.36.0, and zod. Updated monthly. Differentiator: declarative @Transactional decorator with automatic commit/rollback tied to request lifecycle, reducing boilerplate for Najm-based APIs.","status":"active","version":"1.1.8","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","database","transaction","najm","decorator","orm","api","framework","typescript"],"install":[{"cmd":"npm install najm-database","lang":"bash","label":"npm"},{"cmd":"yarn add najm-database","lang":"bash","label":"yarn"},{"cmd":"pnpm add najm-database","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"core framework dependency","package":"najm-core","optional":true},{"reason":"required for decorator functionality","package":"reflect-metadata","optional":false},{"reason":"peer dependency for database operations","package":"drizzle-orm","optional":true},{"reason":"peer dependency for schema validation","package":"zod","optional":true}],"imports":[{"note":"ESM-only since v1.0.0. Named export.","wrong":"const DatabasePlugin = require('najm-database').DatabasePlugin","symbol":"DatabasePlugin","correct":"import { DatabasePlugin } from 'najm-database'"},{"note":"Named export, not default. Used as @Transactional decorator.","wrong":"import Transactional from 'najm-database'","symbol":"Transactional","correct":"import { Transactional } from 'najm-database'"},{"note":"Type export. Should use `import type` in TypeScript to avoid runtime overhead.","wrong":"import { DatabaseConfig } from 'najm-database'","symbol":"DatabaseConfig","correct":"import type { DatabaseConfig } from 'najm-database'"},{"note":"Default export is the main plugin class. Named export NajmDatabase does not exist.","wrong":"import { NajmDatabase } from 'najm-database'","symbol":"default","correct":"import NajmDatabase from 'najm-database'"}],"quickstart":{"code":"import { DatabasePlugin, Transactional } from 'najm-database';\nimport { drizzle } from 'drizzle-orm/node-postgres';\nimport { Pool } from 'pg';\n\nconst pool = new Pool({ connectionString: process.env.DB_URL ?? '' });\nconst db = drizzle(pool);\n\n// Register plugin with Najm framework\nimport { Najm } from 'najm-core';\nconst app = new Najm();\napp.use(DatabasePlugin, { db });\n\n// Use @Transactional decorator in a service\nclass UserService {\n  @Transactional()\n  async createUser(data: { name: string }) {\n    // This method runs inside a database transaction\n    // Automatically commits on success, rolls back on error\n    return await db.insert(users).values(data).returning();\n  }\n}","lang":"typescript","description":"Shows how to initialize the DatabasePlugin with a Drizzle ORM instance and use the @Transactional decorator on a method to wrap it in a database transaction."},"warnings":[{"fix":"Replace require() with import statements. Use dynamic import if necessary.","message":"Version 1.0.0 removed CommonJS support. All imports must use ESM syntax.","severity":"breaking","affected_versions":">=1.0.0 <2.0.0"},{"fix":"Use `new DatabasePlugin({ db: drizzleInstance })` instead of `new DatabasePlugin(drizzleInstance)`.","message":"The `DatabasePlugin` constructor now requires an options object with `db` property. Passing a direct Drizzle instance is deprecated.","severity":"deprecated","affected_versions":">=1.1.0"},{"fix":"Ensure the class is registered as a service or component in Najm.","message":"The @Transactional decorator only works on methods inside classes that are instantiated by the Najm framework container. Manually instantiated classes will not have transaction support.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Add `import 'reflect-metadata'` at the top of your main file.","message":"reflect-metadata must be imported at the application entry point before any decorator usage, otherwise @Transactional will throw 'Reflect.getMetadata is not a function'.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Add `import 'reflect-metadata'` to the top of the entry file.","cause":"reflect-metadata polyfill not imported before decorator usage.","error":"Reflect.getMetadata is not a function"},{"fix":"Run `npm install —legacy-peer-deps` and ensure package.json has `\"type\": \"module\"`.","cause":"Missing peer dependency najm-core or incorrect Node.js version (requires ESM).","error":"Cannot find module 'najm-database' or its corresponding type declarations"},{"fix":"Convert project to ESM or use dynamic import: `const { DatabasePlugin } = await import('najm-database')`.","cause":"CommonJS context (require) cannot handle ESM-only package.","error":"SyntaxError: Unexpected token 'export'"},{"fix":"Instantiate with `new DatabasePlugin({ db })`.","cause":"Using `DatabasePlugin()` instead of `new DatabasePlugin()`.","error":"TypeError: Class constructor DatabasePlugin cannot be invoked without 'new'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}