better-auth-cloudflare
better-auth-cloudflare is a plugin designed to seamlessly integrate the Better Auth library with the Cloudflare ecosystem, including Workers, D1, Hyperdrive, KV, R2, and geolocation services. It is currently at version 0.3.0 and actively maintained with a continuous release cadence, addressing new features and compatibility updates. This library differentiates itself by providing out-of-the-box support for Cloudflare's serverless offerings, allowing developers to leverage D1 (SQLite), Postgres, and MySQL (via Drizzle ORM or native D1), KV for session caching, and R2 for file storage. It also automatically enriches user sessions with Cloudflare's geolocation and IP detection data, offering a comprehensive solution for authentication in Cloudflare environments without extensive manual setup, making it ideal for Hono, OpenNextJS, and other Worker-compatible frameworks.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to use `better-auth-cloudflare` with CommonJS `require()` syntax in a Node.js or Cloudflare Worker environment that expects ES Modules.fixMigrate your project to use ES Modules. Use `import` statements instead of `require()`. Ensure your `package.json` specifies `"type": "module"` or uses `.mjs` file extensions. -
Failed to generate auth schema
cause This error can occur when using the `@better-auth/cli` commands (e.g., `npx better-auth-cloudflare@latest generate`) with `bunx` due to compatibility issues.fixPrefer `npm` for executing CLI commands. Use `npx better-auth-cloudflare@latest generate` instead of `bunx better-auth-cloudflare@latest generate`.
Warnings
- breaking The minimum peer dependency for `better-auth` has been raised from `^1.1.21` to `^1.5.0`.
- breaking A new peer dependency, `@better-auth/drizzle-adapter` (`^1.5.0`), is now required if you are using Drizzle-based database options (D1, Postgres, MySQL) with `better-auth-cloudflare`.
- gotcha Cloudflare KV storage requires a minimum TTL (Time-To-Live) of 60 seconds for entries. Setting a TTL below this value will be clamped to 60 seconds or result in an error in some environments.
- gotcha R2 uploads might fail with a 415 error (Unsupported Media Type) if `allowedMediaTypes` are not correctly specified or if the client sends an unsupported `Content-Type` header.
Install
-
npm install better-auth-cloudflare -
yarn add better-auth-cloudflare -
pnpm add better-auth-cloudflare
Imports
- withCloudflare
const { withCloudflare } = require('better-auth-cloudflare');import { withCloudflare } from 'better-auth-cloudflare'; - CloudflareSession
import { CloudflareSession } from 'better-auth-cloudflare';import type { CloudflareSession } from 'better-auth-cloudflare'; - BetterAuthCloudflareOptions
import { BetterAuthCloudflareOptions } from 'better-auth-cloudflare';import type { BetterAuthCloudflareOptions } from 'better-auth-cloudflare';
Quickstart
import { withCloudflare } from 'better-auth-cloudflare';
import { BetterAuth } from 'better-auth';
import { Hono } from 'hono';
import { Env } from './env'; // Assume a types file for Cloudflare Bindings
// Initialize the core BetterAuth instance
const auth = new BetterAuth({
secret: process.env.AUTH_SECRET ?? 'super-secret-key-please-change',
// ... other better-auth configuration like adapters, providers
});
// Create a Hono app, assuming it's your Cloudflare Worker entry point
const app = new Hono<{ Bindings: Env }>();
// Integrate BetterAuth with Cloudflare services using `withCloudflare`
const cloudflareAuth = withCloudflare(auth, {
// Use the D1Database binding directly (new in v0.3.0)
d1Native: (env) => env.D1_DATABASE,
// Optional: Cloudflare KV for secondary storage/caching
kv: (env) => env.KV_STORAGE,
// Optional: Cloudflare R2 for file storage
r2: (env) => env.R2_BUCKET,
// Cloudflare-specific configurations are passed here
});
// Mount the better-auth routes to your Hono application
app.route('/auth', cloudflareAuth.router);
// Example route demonstrating session and geolocation access
app.get('/', (c) => {
const session = cloudflareAuth.getSession(c);
const user = session?.user;
const geolocation = session?.geolocation;
const message = user
? `Hello ${user.name} from ${geolocation?.city}, ${geolocation?.country}!`
: 'Hello, guest! Please log in.';
return c.text(message);
});
// Export the Hono app for Cloudflare Workers
export default app;