@mertdogar/better-auth-do-sqlite
A Better Auth adapter for Cloudflare Durable Objects with SQLite storage. This library enables you to use Better Auth's authentication features in Cloudflare Workers with Durable Objects as your database layer.
Features
- 🔐 Full Better Auth integration with Cloudflare Durable Objects
- 💾 SQLite storage via Durable Objects
- 🚀 Built for Cloudflare Workers
- 🎯 Type-safe with TypeScript
- 🔄 Session management with Durable Objects
- 🛠️ Works seamlessly with Hono and other frameworks
Installation
npm install @mertdogar/better-auth-do-sqlite better-auth hono
Or with other package managers:
pnpm add @mertdogar/better-auth-do-sqlite better-auth hono
yarn add @mertdogar/better-auth-do-sqlite better-auth hono
bun add @mertdogar/better-auth-do-sqlite better-auth hono
Quick Start
1. Configure Wrangler
Create or update your wrangler.jsonc:
{
"name": "my-auth-app",
"main": "src/index.ts",
"compatibility_date": "2025-05-04",
"vars": {
"JWT_SECRET": "your-secret-key-here",
},
"durable_objects": {
"bindings": [
{
"class_name": "APPDO",
"name": "APP_DO",
},
],
},
"migrations": [
{
"new_sqlite_classes": ["APPDO"],
"tag": "v1",
},
],
}
2. Create Worker Types
Create a worker-configuration.d.ts file:
interface Env extends Cloudflare.Env {
JWT_SECRET: string
APP_DO: DurableObjectNamespace
}
3. Implement Your Worker
import { Hono } from 'hono'
import { AuthDO, authMiddleware, betterAuthRouter, getDO } from '@mertdogar/better-auth-do-sqlite'
export class APPDO extends AuthDO {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
}
}
const app = new Hono<{ Bindings: Env }>()
app.use('*', authMiddleware('app'))
app.route('/api/auth', betterAuthRouter('app'))
app.get('/', async (c) => {
const appDO = getDO(c, 'app')
const session = await appDO.getActiveSession(c.req.raw)
if (!session) {
return c.json({ error: 'Unauthorized' }, 401)
}
return c.json({ message: 'Hello authenticated user!', session })
})
export default app
API Reference
AuthDO
The base Durable Object class that provides authentication functionality.
export class APPDO extends AuthDO {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env)
}
}
Methods
-
getActiveSession(request: Request): Promise<Session | null>
Retrieves the active session for the given request.
const session = await appDO.getActiveSession(request)
authMiddleware(bindingPrefix: string)
Middleware that attaches authentication context to requests.
Parameters:
bindingPrefix: The prefix of your Durable Object binding (e.g., 'app' for APP_DO)
app.use('*', authMiddleware('app'))
betterAuthRouter(bindingPrefix: string)
Hono router that handles all Better Auth endpoints.
Parameters:
bindingPrefix: The prefix of your Durable Object binding (e.g., 'app' for APP_DO)
app.route('/api/auth', betterAuthRouter('app'))
This will create the following endpoints:
POST /api/auth/sign-in
POST /api/auth/sign-up
POST /api/auth/sign-out
GET /api/auth/session
- And all other Better Auth endpoints
getDO(context: HonoContext, bindingPrefix: string)
Helper function to get the Durable Object instance.
Parameters:
context: Hono context object
bindingPrefix: The prefix of your Durable Object binding
const appDO = getDO(c, 'app')
Configuration
Environment Variables
Set these in your wrangler.jsonc or .dev.vars file:
JWT_SECRET=your-secret-key-here-min-32-characters
Durable Object Binding
The library expects a Durable Object binding with the pattern {PREFIX}_DO. For example:
- If you use
authMiddleware('app'), you need an APP_DO binding
- If you use
authMiddleware('auth'), you need an AUTH_DO binding
Advanced Usage
Custom Session Handling
app.get('/profile', async (c) => {
const appDO = getDO(c, 'app')
const session = await appDO.getActiveSession(c.req.raw)
if (!session) {
return c.json({ error: 'Unauthorized' }, 401)
}
return c.json({
userId: session.userId,
email: session.user?.email,
})
})
Multiple Authentication Domains
You can use multiple Durable Object instances for different authentication domains:
export class UserAuthDO extends AuthDO {}
export class AdminAuthDO extends AuthDO {}
const app = new Hono()
app.use('/user/*', authMiddleware('userAuth'))
app.route('/user/auth', betterAuthRouter('userAuth'))
app.use('/admin/*', authMiddleware('adminAuth'))
app.route('/admin/auth', betterAuthRouter('adminAuth'))
Development
npm install
npm run dev
npm run deploy
How It Works
This library leverages Cloudflare Durable Objects with SQLite to provide a serverless, edge-based authentication solution:
- Durable Objects: Each authentication instance runs in a Durable Object, providing strong consistency and SQLite storage
- Better Auth Integration: Full Better Auth functionality is available through the Durable Object interface
- Edge Performance: Authentication runs at the edge, close to your users
- Persistent Storage: SQLite in Durable Objects ensures your authentication data persists
Requirements
- Node.js 16.x or later (or Bun)
- Cloudflare Workers account
- Wrangler CLI (
npm install -g wrangler)
Limitations
- Durable Objects have usage limits that should be considered
- SQLite storage in Durable Objects is persistent per object instance
- Authentication state is isolated per Durable Object instance
Troubleshooting
"Durable Object not found" Error
Make sure your Durable Object binding matches the prefix you're using:
Session Not Persisting
Ensure your JWT_SECRET is set and is at least 32 characters long.
TypeScript Errors
Make sure you have the worker types configured:
npm run types
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details
Related
Support