npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@mertdogar/better-auth-do-sqlite

v0.0.25

Published

Complete authentication and database solution for Cloudflare Durable Objects with Better Auth and libSQL HTTP protocol support

Readme

@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
pnpm add @mertdogar/better-auth-do-sqlite better-auth hono

# yarn
yarn add @mertdogar/better-auth-do-sqlite better-auth hono

# bun
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
  APP_DO_ID?: string // Optional: defaults to 'app'
}

3. Implement Your Worker

import { Hono } from 'hono'
import { AuthDO, authMiddleware, betterAuthRouter, getDO } from '@mertdogar/better-auth-do-sqlite'

// Extend AuthDO to create your Durable Object class
export class APPDO extends AuthDO {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env)
  }
}

const app = new Hono<{ Bindings: Env }>()

// Apply auth middleware globally
app.use('*', authMiddleware())

// Mount Better Auth routes
app.route('/api/auth', betterAuthRouter())

// Protected route example
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()

Hono middleware that injects session information into the context.

app.use('*', authMiddleware())

The middleware reads APP_DO_ID from c.env (defaults to 'app' if not set).

betterAuthRouter<E>()

Hono router that handles all Better Auth endpoints. Generic type parameter allows type-safe integration with your app's environment.

// Basic usage
app.route('/api/auth', betterAuthRouter())

// With explicit types
app.route('/api/auth', betterAuthRouter<{ Bindings: Env }>())

The router reads APP_DO_ID from c.env (defaults to 'app' if not set).

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, doId: string)

Helper function to get the Durable Object instance.

Parameters:

  • context: Hono context object
  • doId: The Durable Object instance ID/name
const appDO = getDO(c, 'app')

sqlServerRouter<E>()

Hono router that proxies libSQL HTTP protocol requests to the Durable Object. Generic type parameter allows type-safe integration.

// Basic usage
app.route('/api/sqld', sqlServerRouter())

// With explicit types
app.route('/api/sqld', sqlServerRouter<{ Bindings: Env }>())

The router reads APP_DO_ID and optional prefixRegex from c.env.

Configuration

Environment Variables

Set these in your wrangler.jsonc or .dev.vars file:

# Required
JWT_SECRET=your-secret-key-here-min-32-characters

# Optional - for development
# Add other Better Auth configuration as needed

Durable Object Binding

The library expects a Durable Object binding named APP_DO in your wrangler.jsonc. The middleware and routers read APP_DO_ID from c.env to determine which Durable Object instance to use:

// Default behavior: uses instance ID 'app'
app.use('*', authMiddleware())

// Custom instance: set APP_DO_ID dynamically
app.use('/tenant/:id/*', async (c, next) => {
  c.env.APP_DO_ID = c.req.param('id')
  return authMiddleware()(c, next)
})

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)
  }

  // Access user information from session
  return c.json({
    userId: session.userId,
    email: session.user?.email,
    // ... other session data
  })
})

Multiple Authentication Domains

You can use multiple Durable Object instances for different authentication domains by setting different APP_DO_ID values:

// User authentication
export class UserAuthDO extends AuthDO {}

// Admin authentication
export class AdminAuthDO extends AuthDO {}

interface Env {
  JWT_SECRET: string
  USER_AUTH_DO: DurableObjectNamespace
  ADMIN_AUTH_DO: DurableObjectNamespace
  APP_DO: DurableObjectNamespace
}

const app = new Hono<{ Bindings: Env }>()

// User routes - set APP_DO_ID to 'userAuth'
app.use('/user/*', async (c, next) => {
  c.env.APP_DO_ID = 'userAuth'
  return authMiddleware()(c, next)
})
app.route('/user/auth', betterAuthRouter())

// Admin routes - set APP_DO_ID to 'adminAuth'
app.use('/admin/*', async (c, next) => {
  c.env.APP_DO_ID = 'adminAuth'
  return authMiddleware()(c, next)
})
app.route('/admin/auth', betterAuthRouter())

Development

# Install dependencies
npm install

# Start development server
npm run dev

# Deploy to Cloudflare
npm run deploy

How It Works

This library leverages Cloudflare Durable Objects with SQLite to provide a serverless, edge-based authentication solution:

  1. Durable Objects: Each authentication instance runs in a Durable Object, providing strong consistency and SQLite storage
  2. Better Auth Integration: Full Better Auth functionality is available through the Durable Object interface
  3. Edge Performance: Authentication runs at the edge, close to your users
  4. 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:

// If using authMiddleware('app')
// Your binding should be APP_DO (uppercase {PREFIX}_DO)

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  # or: wrangler types

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Related

Support