If you've shipped a Next.js app on NextAuth (now Auth.js), you know it works. The reason people move to Better Auth usually isn't that NextAuth is bad — it's that Better Auth gives you typed, first-class access to sessions, organizations, and database-backed concepts without bolting adapters and callbacks together by hand. The session calls are typed end to end, the schema is generated for you, and features like multi-tenancy or admin tooling are first-party rather than community glue.

This post is the honest version of that migration: the mechanical parts you can rewrite almost blindly, and the parts you still have to do by hand. I'll show real before/after code for each.

Coming from Clerk instead? See the companion guide: Moving off Clerk to Better Auth.

The mental model: NextAuth is a library, so a lot of the rewrite is mechanical

Much of a NextAuth integration is call sites — getServerSession here, useSession there, a signIn button. Those follow patterns, which means they're transformable. The part that isn't mechanical is your configuration: providers, the database adapter, and callbacks. That's the logic only you understand, and no tool should silently rewrite it.