better-auth-effect
raw JSON → 0.4.1 verified Sat Apr 25 auth: no javascript
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+.
Common errors
error TypeError: effectSqlAdapter is not a function ↓
cause Importing from wrong path or incorrect import style (e.g., require() in ESM package).
fix
Use import { effectSqlAdapter } from 'better-auth-effect' with native ESM.
error Error: The runtime argument must be an Effect Runtime, got undefined ↓
cause Runtime not provided or incorrectly extracted from Effect context.
fix
Ensure runtime is obtained via Effect.runtime<SqlClient>() inside a Layer.
error Error: Dialect must be one of: 'pg', 'mysql', 'sqlite' ↓
cause Invalid dialect string passed to effectSqlAdapter config.
fix
Use 'pg' for PostgreSQL, 'mysql' for MySQL, or 'sqlite' for SQLite.
Warnings
breaking Package is ESM-only; require() throws ERR_MODULE_NOT_FOUND ↓
fix Use import or set type: module in package.json. For CommonJS projects, use dynamic import: const { effectSqlAdapter } = await import('better-auth-effect')
gotcha Runtime must be obtained from Effect.runtime() inside a Layer or from ManagedRuntime, not created manually ↓
fix Use Effect.runtime<SqlClient>() inside a Layer or ManagedRuntime.make().runtime() to get the Runtime.
gotcha MySQL dialect emulates RETURNING via LAST_INSERT_ID() + SELECT; requires id column as primary key on all tables ↓
fix Ensure all database tables (user, account, session, verification) have an id column with auto-increment primary key.
deprecated V0.3.x used a different configuration API; v0.4.0 introduced Runtime-based config ↓
fix Upgrade to v0.4+ and pass { runtime, dialect, debugLogs? } instead of previous SqlClient parameter.
Install
npm install better-auth-effect yarn add better-auth-effect pnpm add better-auth-effect Imports
- effectSqlAdapter wrong
const { effectSqlAdapter } = require('better-auth-effect')correctimport { effectSqlAdapter } from 'better-auth-effect' - EffectSqlAdapterConfig wrong
import { EffectSqlAdapterConfig } from 'better-auth-effect'correctimport type { EffectSqlAdapterConfig } from 'better-auth-effect' - default import wrong
import { default as effectSqlAdapter } from 'better-auth-effect'correctimport effectSqlAdapter from 'better-auth-effect'
Quickstart
import { Effect, Layer, ManagedRuntime } from 'effect'
import { SqlClient } from '@effect/sql'
import { PgClient } from '@effect/sql-pg'
import { betterAuth } from 'better-auth'
import { effectSqlAdapter } from 'better-auth-effect'
// Build the SQL layer
const DatabaseLive = PgClient.layer({
url: 'postgresql://postgres:password@localhost:5432/myapp',
})
// Build auth layer with adapter
const AuthLive = Layer.scoped(
Effect.Do.pipe(
Effect.flatMap(() => Effect.runtime<SqlClient.SqlClient>()),
Effect.map((rt) =>
betterAuth({
database: effectSqlAdapter({ runtime: rt, dialect: 'pg' }),
})
)
)
).pipe(Layer.provide(DatabaseLive))
// Run the application
const runtime = ManagedRuntime.make(Layer.mergeAll(AuthLive, DatabaseLive))
// Use runtime to run effects with auth
console.log('Auth adapter configured successfully')