ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-04-30Advanced

Antigravity × Better Auth: Building a Modern TypeScript Auth Stack End-to-End

End the NextAuth fatigue with Better Auth. A practical Antigravity-driven guide that ships schema generation, OAuth, RBAC, and Passkeys with production-ready patterns.

antigravity362better-authauthentication6typescript26nextjs4rbac2

Premium Article

"Do I really have to rewrite auth.ts again?" If that thought sounds familiar, you're not alone. Auth.js v5 cleaned up a lot of NextAuth's old quirks, but staring down generic type errors in [...nextauth]/route.ts is still a rite of passage I personally know too well.

Lately, a TypeScript-native, framework-agnostic, plugin-driven library called Better Auth has been quietly winning hearts in the indie and startup world. In this article, I'll walk through how I use Antigravity's agent as a dedicated "auth engineer" to scaffold a Better Auth setup from scratch, all the way through to the production traps that bite real projects.

Why Better Auth, and how it differs from Auth.js v5

Better Auth and Auth.js v5 enter through the same door — "user authentication library" — but their design philosophies diverge sharply. Auth.js is tightly integrated with Next.js's App Router, while Better Auth is a headless library that exposes raw HTTP handlers.

That difference shows up immediately when you scaffold with Antigravity. With Auth.js you have to keep auth.ts and route.ts in sync, and you find yourself adding "make sure both files agree" to every prompt. Better Auth pushes all the logic into one auth.ts, while the HTTP layer is just auth.handler. The cognitive load on the agent — and on you — drops noticeably.

The three things that finally tipped me over personally:

  • Database schema is generated declaratively — your Drizzle/Prisma schema file is emitted by a CLI command
  • Passkeys, magic links, and 2FA layer in cleanly via plugins — the core stays small
  • It runs on edge runtimes — Cloudflare Workers and Vercel Edge don't break it

You can argue that Auth.js can do all of this (the up-to-date Auth.js v5 patterns are covered in Antigravity × Auth.js v5 Authentication Guide). The problem is the number of "right ways" to do it varies by every blog post you read. Better Auth is more opinionated, which makes it much easier for an Antigravity agent to internalize a single canonical pattern.

Stack assumptions and project bootstrap

The samples in this article assume Next.js 16 (App Router) + TypeScript 5.6 + Drizzle ORM + Cloudflare D1. The database adapter swap is straightforward — PostgreSQL via Neon or Prisma works the same way — so feel free to translate to whatever stack you live in.

# Bootstrap the base project
pnpm create next-app@latest my-saas --typescript --app --eslint --tailwind --src-dir
cd my-saas
 
# Install auth + DB libraries
pnpm add better-auth drizzle-orm
pnpm add -D drizzle-kit @types/bun
 
# For Cloudflare D1
pnpm add @cloudflare/workers-types better-sqlite3

When you open this project in Antigravity, the very first thing I'd do is add a line to AGENTS.md: "This project uses Better Auth. Do not propose Auth.js as an alternative." That single sentence keeps the agent's recommendations stable across long sessions.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
If you've been worn down by NextAuth/Auth.js v5 complexity, you'll get a clear set of decision points and step-by-step instructions for migrating a real project to Better Auth
You'll learn how to drive Antigravity agents through the entire stack — schema generation, OAuth, RBAC, Passkeys — with prompt patterns that actually hold up in production
You'll come away with the cookie, CSRF, session expiry, and multi-tenant isolation traps already mapped out, with the working code shown next to the broken version
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-06-14
When the Edge Cache Pinned Next.js Error Pages: A cache-worker Guard Design
Users reported intermittent 'failed to load' errors I could never reproduce. The cause: SSR exceptions shipped as HTTP 200 and pinned by the edge cache. Here is how I narrowed it down with an Antigravity agent and added a cache-worker guard to stop it.
App Dev2026-05-03
Building Idempotency Keys and Dedupe Stores in TypeScript with Antigravity
A production guide to designing idempotency keys and dedupe stores in TypeScript with Antigravity — covering Stripe webhook retries, Temporal replays, and the Cloudflare KV / Redis / Postgres trade-offs you actually need to choose between.
App Dev2026-05-02
Stopping Server Action Foot-Guns Before Antigravity Ships Them — Zod, revalidate, and Authorization Built In From the First Draft
Ask Antigravity to write a Next.js Server Action and you'll often get back code with no Zod parsing, no revalidate call, and no authorization check. Here's how to bake those in from the start instead of patching them on later.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →