惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Forbes - Security
Forbes - Security
C
CERT Recently Published Vulnerability Notes
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Secure Thoughts
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
N
News | PayPal Newsroom
人人都是产品经理
人人都是产品经理
S
Securelist
J
Java Code Geeks
月光博客
月光博客
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
Hugging Face - Blog
Hugging Face - Blog
T
Threatpost
H
Hacker News: Front Page
Recent Commits to openclaw:main
Recent Commits to openclaw:main
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
PCI Perspectives
PCI Perspectives
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Google DeepMind News
Google DeepMind News
量子位
SecWiki News
SecWiki News
有赞技术团队
有赞技术团队
TaoSecurity Blog
TaoSecurity Blog
N
Netflix TechBlog - Medium
Latest news
Latest news
博客园_首页
L
LINUX DO - 最新话题
V
Visual Studio Blog
G
Google Developers Blog
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tenable Blog
Simon Willison's Weblog
Simon Willison's Weblog
Scott Helme
Scott Helme
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Privacy International News Feed
Recorded Future
Recorded Future
Stack Overflow Blog
Stack Overflow Blog
O
OpenAI News
T
Tor Project blog
IT之家
IT之家
S
SegmentFault 最新的问题

Flavio Copes

Cloudflare Artifacts: Git storage built for AI agents Workers Cache: a cache in front of your Cloudflare Worker Cloudflare Drop: drag a folder, get a live site Temporary Cloudflare accounts: agents can now deploy without signing up Moondream 3.1 on Workers AI: fast vision at the edge inferencecost.dev: what will AI inference cost you at 10k users? Sitebase: all the features your website needs, in one place StackPlan: figure out where to deploy your app, and what it How the Cloudflare Pages build cache works The Summer of Code How I generate an Open Graph image for every post New: 90 free tools for developers How I added search to my static site with Pagefind How to rebuild a Cloudflare site on a schedule Cloudflare Email Workers: run code when an email arrives Cloudflare Turnstile: stop bots without annoying CAPTCHAs Cloudflare Workers: secrets and environments Cloudflare Workers observability: logs and traces Cloudflare Analytics Engine: store and query metrics The AI Workshop (July 2026 cohort) Cloudflare Cron Triggers: run a Worker on a schedule Cloudflare Durable Objects: state that lives in one place Cloudflare Queues: run work in the background Cloudflare R2: object storage without egress fees Cloudflare KV: a key-value store for your Workers Cloudflare D1: a SQL database for your Workers Serving a website with Cloudflare Workers static assets Wrangler: the Cloudflare Workers command line tool Executor: one gateway to connect your AI agent to every tool Cloudflare Workers: your first serverless function Vercel eve: an open framework for building AI agents Flue: the open framework for building AI agents Val Town: write and deploy code in seconds A hands-on guide to The Agency, a collection of AI agents The AI Workshop (June 2026 cohort) The AI Workshop (May 2026 cohort) The AI Workshop (Apr 2026 cohort)
Better Auth: an introduction
Flavio Copes · 2026-07-10 · via Flavio Copes

By Flavio Copes

What Better Auth is and how it works: the auth instance, the database schema, the catch-all route, and the client. Authentication for TypeScript apps, explained.

~~~

Authentication is one of those things you need in almost every app, and one of those things you really don’t want to build yourself.

Sessions, password hashing, OAuth flows, email verification… it’s a lot of code, and getting it wrong has real consequences.

For years the answer was either a hosted service (Auth0, Clerk, Supabase Auth) or wiring things up yourself with something like Lucia. Better Auth is the option I reach for now: a TypeScript library that runs inside your app and stores users in your database.

That’s the key difference from hosted services. Your users live in your own tables. No external dashboard, no per-user pricing, no vendor lock-in. It’s just a library.

How it works

Better Auth has two halves:

  • a server instance that handles all the auth logic and talks to your database
  • a client that your frontend uses to sign users up, sign them in, and read the session

The server instance exposes everything through a single HTTP handler you mount at /api/auth/*. The client calls those endpoints for you. You never write the endpoints yourself.

The server instance

You install it first:

npm i better-auth

Then create the instance, usually in a file called auth.ts:

import { betterAuth } from 'better-auth'
import { Pool } from 'pg'

export const auth = betterAuth({
  database: new Pool({
    connectionString: process.env.DATABASE_URL,
  }),
  emailAndPassword: {
    enabled: true,
  },
})

This one connects to Postgres and enables email + password login. Better Auth also works with MySQL and SQLite, and has adapters for Drizzle and Prisma if you already use an ORM.

Want social login? Add the provider and its credentials:

socialProviders: {
  github: {
    clientId: process.env.GITHUB_CLIENT_ID,
    clientSecret: process.env.GITHUB_CLIENT_SECRET,
  },
},

The database schema

Better Auth needs a few tables: user, session, account, and verification.

You don’t write them by hand. The CLI generates them from your config:

npx @better-auth/cli generate

If you use Drizzle or Prisma, this writes the schema in your ORM’s format. Then you run your normal migrations and you’re done.

Mounting the handler

The instance has a handler function that takes a standard Request and returns a Response. You mount it on a catch-all route.

In Next.js, for example:

// app/api/auth/[...all]/route.ts
import { auth } from '@/lib/auth'
import { toNextJsHandler } from 'better-auth/next-js'

export const { GET, POST } = toNextJsHandler(auth)

Every framework has its own one-liner for this. Since the handler works on plain Request/Response objects, it runs anywhere the Fetch API works: Node, Bun, Deno, Cloudflare Workers.

The client

On the frontend you create a client:

// lib/auth-client.ts
import { createAuthClient } from 'better-auth/client'

export const authClient = createAuthClient()

Now you can sign users up:

await authClient.signUp.email({
  name: 'Flavio',
  email: '[email protected]',
  password: 'a-strong-password',
})

Sign them in:

await authClient.signIn.email({
  email: '[email protected]',
  password: 'a-strong-password',
})

Or with a social provider:

await authClient.signIn.social({ provider: 'github' })

And sign them out:

await authClient.signOut()

Sessions are handled with secure cookies. You don’t manage tokens yourself.

Reading the session

On the client, React and Vue get a reactive useSession hook:

const { data: session } = authClient.useSession()

When the user signs in or out, components using the hook re-render automatically.

On the server, you ask the auth instance directly, passing the request headers so it can read the cookie:

const session = await auth.api.getSession({
  headers: request.headers,
})

if (!session) {
  // not logged in
}

This is what you use in middleware or route handlers to protect pages.

Plugins

Everything beyond the basics is a plugin: two-factor authentication, magic links, passkeys, organizations and teams, username login. You add them to the server instance and the client, run the CLI to update the schema, and the new endpoints appear.

This is what I like most about the design. The core stays small, and you only pull in what you need.

My advice: if you’re starting a new TypeScript project and you own your database, try Better Auth before reaching for a hosted service. You get the convenience of a managed solution, but the users stay yours.

~~~

Related posts about js: