◉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.

antigravity470better-authauthentication10typescript28nextjs4rbac

✦ 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.

This is the record of putting Antigravity's agent to work as a dedicated "auth engineer" and building a Better Auth stack from nothing. Rather than restating the setup steps, I've organised it around what only showed up once I had my hands on the code: the places where moving a config key one level over kills a feature without raising a single error.

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 (a more conventional stack is covered in Building a Next.js SaaS with Antigravity: Auth, Stripe, and D1). 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-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-04-29
Composing Event-Driven AI Workflows with Antigravity and Inngest — A Production-Ready Implementation Guide
A hands-on production guide to wiring Antigravity's AI agents with Inngest. Cover idempotency, concurrency control, human-in-the-loop, retry classification, and observability with copy-pasteable code.
▣ App Dev2026-10-14
Before Turning Undocumented Code Into a Spec, Decide the Reading Order by Fan-In
When you ask an agent to turn undocumented code into a spec, which files do you hand over first? A 36-line Python script ranks files by import count (fan-in) plus route entry points, with measurements from a 77-file Next.js project.