{"id":18155,"library":"better-auth-effect","title":"better-auth-effect","description":"Better Auth database adapter for @effect/sql, version 0.4.1. Integrates Better Auth authentication with Effect SQL ecosystem, supporting PostgreSQL, MySQL, and SQLite via @effect/sql-pg, @effect/sql-mysql2, and @effect/sql-sqlite-node. Released as a thin adapter that accepts an Effect Runtime to share the connection pool, avoiding manual lifecycle management. Supports all Better Auth adapter operations (create, findOne, findMany, update, delete, etc.) and handles database dialect differences like RETURNING clauses. Requires Effect v3.15+, Better Auth v1.2+, and Node.js 20+.","status":"active","version":"0.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/alex-golubev/better-auth-effect-adapter","tags":["javascript","better-auth","effect","effect-ts","sql","adapter","authentication","auth","typescript"],"install":[{"cmd":"npm install better-auth-effect","lang":"bash","label":"npm"},{"cmd":"yarn add better-auth-effect","lang":"bash","label":"yarn"},{"cmd":"pnpm add better-auth-effect","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency: provides SqlClient abstraction for database operations.","package":"@effect/sql","optional":false},{"reason":"Peer dependency: core authentication library.","package":"better-auth","optional":false},{"reason":"Peer dependency: provides Effect runtime and Layer system.","package":"effect","optional":false}],"imports":[{"note":"Package is ESM-only since v0.1.0; require() will fail with ERR_MODULE_NOT_FOUND.","wrong":"const { effectSqlAdapter } = require('better-auth-effect')","symbol":"effectSqlAdapter","correct":"import { effectSqlAdapter } from 'better-auth-effect'"},{"note":"This is a TypeScript type, not a runtime value. Use import type to avoid runtime errors.","wrong":"import { EffectSqlAdapterConfig } from 'better-auth-effect'","symbol":"EffectSqlAdapterConfig","correct":"import type { EffectSqlAdapterConfig } from 'better-auth-effect'"},{"note":"Package has both a default export (the adapter function) and a named export. The default export is the same as the named one.","wrong":"import { default as effectSqlAdapter } from 'better-auth-effect'","symbol":"default import","correct":"import effectSqlAdapter from 'better-auth-effect'"}],"quickstart":{"code":"import { Effect, Layer, ManagedRuntime } from 'effect'\nimport { SqlClient } from '@effect/sql'\nimport { PgClient } from '@effect/sql-pg'\nimport { betterAuth } from 'better-auth'\nimport { effectSqlAdapter } from 'better-auth-effect'\n\n// Build the SQL layer\nconst DatabaseLive = PgClient.layer({\n  url: 'postgresql://postgres:password@localhost:5432/myapp',\n})\n\n// Build auth layer with adapter\nconst AuthLive = Layer.scoped(\n  Effect.Do.pipe(\n    Effect.flatMap(() => Effect.runtime<SqlClient.SqlClient>()),\n    Effect.map((rt) =>\n      betterAuth({\n        database: effectSqlAdapter({ runtime: rt, dialect: 'pg' }),\n      })\n    )\n  )\n).pipe(Layer.provide(DatabaseLive))\n\n// Run the application\nconst runtime = ManagedRuntime.make(Layer.mergeAll(AuthLive, DatabaseLive))\n// Use runtime to run effects with auth\nconsole.log('Auth adapter configured successfully')","lang":"typescript","description":"Sets up Better Auth with Effect SQL PostgreSQL adapter using Runtime injection, showing layer composition and ManagedRuntime usage."},"warnings":[{"fix":"Use import or set type: module in package.json. For CommonJS projects, use dynamic import: const { effectSqlAdapter } = await import('better-auth-effect')","message":"Package is ESM-only; require() throws ERR_MODULE_NOT_FOUND","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Use Effect.runtime<SqlClient>() inside a Layer or ManagedRuntime.make().runtime() to get the Runtime.","message":"Runtime must be obtained from Effect.runtime() inside a Layer or from ManagedRuntime, not created manually","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Ensure all database tables (user, account, session, verification) have an id column with auto-increment primary key.","message":"MySQL dialect emulates RETURNING via LAST_INSERT_ID() + SELECT; requires id column as primary key on all tables","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Upgrade to v0.4+ and pass { runtime, dialect, debugLogs? } instead of previous SqlClient parameter.","message":"V0.3.x used a different configuration API; v0.4.0 introduced Runtime-based config","severity":"deprecated","affected_versions":"0.3.x"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Use import { effectSqlAdapter } from 'better-auth-effect' with native ESM.","cause":"Importing from wrong path or incorrect import style (e.g., require() in ESM package).","error":"TypeError: effectSqlAdapter is not a function"},{"fix":"Ensure runtime is obtained via Effect.runtime<SqlClient>() inside a Layer.","cause":"Runtime not provided or incorrectly extracted from Effect context.","error":"Error: The runtime argument must be an Effect Runtime, got undefined"},{"fix":"Use 'pg' for PostgreSQL, 'mysql' for MySQL, or 'sqlite' for SQLite.","cause":"Invalid dialect string passed to effectSqlAdapter config.","error":"Error: Dialect must be one of: 'pg', 'mysql', 'sqlite'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}