{"id":43987,"library":"sqlstack","title":"sqlstack","description":"sqlstack (v1.0.25, monthly releases) is a SQL-first data access library for Node.js and TypeScript. It lets developers write real SQL in separate .sql files next to their repository classes, using decorators like @Query and @QueryBinder to bind parameters, execute queries, and shape results—without ORM complexity. Unlike Knex or Prisma, sqlstack keeps full control over SQL and supports Postgres (pg), MySQL (mysql2), and SQLite (better-sqlite3, sqlite3) via adapters. It is ESM-only, requires Node 18+, and ships TypeScript types.","status":"active","version":"1.0.25","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","typescript"],"install":[{"cmd":"npm install sqlstack","lang":"bash","label":"npm"},{"cmd":"yarn add sqlstack","lang":"bash","label":"yarn"},{"cmd":"pnpm add sqlstack","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required when using Postgres adapter","package":"pg","optional":true},{"reason":"Required when using MySQL/MariaDB adapter","package":"mysql2","optional":true},{"reason":"Required when using SQLite adapter","package":"better-sqlite3","optional":true},{"reason":"Alternative SQLite adapter","package":"sqlite3","optional":true}],"imports":[{"note":"SqlStackDB is exported from sqlstack/registry subpath, not from the main entry.","wrong":"import { SqlStackDB } from 'sqlstack'","symbol":"SqlStackDB","correct":"import { SqlStackDB } from 'sqlstack/registry'"},{"note":"Package is ESM-only; use import syntax. require() will fail.","wrong":"const QueryBinder = require('sqlstack').QueryBinder","symbol":"QueryBinder","correct":"import { QueryBinder } from 'sqlstack'"},{"note":"Named import from the main entry.","wrong":null,"symbol":"Query","correct":"import { Query } from 'sqlstack'"},{"note":"Adapter functions are in sqlstack/adapters subpath.","wrong":"import { createPgDb } from 'sqlstack'","symbol":"createPgDb","correct":"import { createPgDb } from 'sqlstack/adapters'"},{"note":"Use this to throw in stub method bodies; it signals to the decorator that the body is placeholder.","wrong":null,"symbol":"SqlStackError","correct":"import { SqlStackError } from 'sqlstack'"}],"quickstart":{"code":"// boot.ts\nimport { SqlStackDB } from \"sqlstack/registry\";\nimport { createPgDb } from \"sqlstack/adapters\";\n\nSqlStackDB\n  .register(\"primary\", createPgDb(process.env.DATABASE_URL ?? \"\"))\n  .setDefault(\"primary\");\n\n// src/users/repository.ts\nimport { QueryBinder, Query, SqlStackError } from \"sqlstack\";\n\n@QueryBinder()\nexport class UsersRepository {\n  @Query()\n  async findByEmail(params: { email: string }): Promise<{ id: string; name: string }[]> {\n    throw new SqlStackError(\"replaced by @Query\");\n  }\n}\n\n// findByEmail.sql next to repository.ts:\n// SELECT id, name FROM users WHERE email = :email;\n\n// usage.ts\nconst repo = new UsersRepository();\nconst users = await repo.findByEmail({ email: \"alice@example.com\" });\nconsole.log(users);","lang":"typescript","description":"Shows registration of a Postgres database, creation of a repository class with @QueryBinder/@Query decorators, and usage of a SQL file to query by email."},"warnings":[{"fix":"Use import syntax instead of require().","message":"Package is ESM-only. Using require() will throw ERR_REQUIRE_ESM.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always throw new SqlStackError('replaced by @Query') in the stub body.","message":"Method bodies in @Query decorated methods must throw SqlStackError; they are never executed but required by TypeScript.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Place .sql files next to your repository class, or specify a custom directory.","message":".sql files must be in the same directory as the class by default. Custom paths require @QueryBinder({ dir: '...' }).","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Install better-sqlite3 and use createBetterSqliteDb instead of createSqliteDb.","message":"Using sqlite3 adapter is deprecated; prefer better-sqlite3 for synchronous SQLite access.","severity":"deprecated","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'18':81 'access':12 'adapt':73 'better':69 'better-sqlite3':68 'bind':40 'class':32 'complex':49 'control':57 'data':11 'decor':34 'develop':20 'esm':77 'esm-on':76 'execut':42 'file':27 'first':10 'full':56 'javascript':86 'keep':55 'knex':51 'let':19 'librari':13 'like':35 'month':4 'mysql':64 'mysql2':65 'next':28 'node':80 'node.js':15 'orm':48 'paramet':41 'pg':63 'postgr':62 'prisma':53 'queri':36,43 'querybind':38 'real':22 'releas':5 'repositori':31 'requir':79 'result':46 'separ':25 'shape':45 'ship':83 'sql':9,23,26,59 'sql-first':8 'sqlite':67 'sqlite3':70,71 'sqlstack':1,2,54 'support':61 'type':85 'typescript':17,84,87 'unlik':50 'use':33 'v1.0.25':3 'via':72 'without':47 'write':21","created_at":"2026-06-05T17:02:26.242096+00:00","updated_at":"2026-06-05T17:02:26.242096+00:00","problems":[{"fix":"Add \"type\": \"module\" to your package.json or use .mjs extension for your files.","cause":"Project is not configured for ESM (e.g., no type: module in package.json or using .cjs extension).","error":"SyntaxError: Cannot use import statement outside a module"},{"fix":"Ensure you call SqlStackDB.register('primary', ...) before using the repository, and that the name matches.","cause":"SqlStackDB.register() was not called or the database name is misspelled.","error":"Error: No database found for name 'primary'"},{"fix":"Instantiate with new UsersRepository().","cause":"Attempting to call the class as a function instead of using new.","error":"TypeError: Class constructor UsersRepository cannot be invoked without 'new'"}],"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":null,"github":null,"docs":null,"changelog":null,"pypi":null,"npm":"sqlstack","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-05","next_check":"2026-09-03","install_tag":null}}