RK
Reetesh Kumar@reetesheth

How Better Auth Quietly Ate the JavaScript Auth Ecosystem

Aug 12, 2026

0

9 min read

For as long as I can remember, authentication in JavaScript was a graveyard of half-solutions. Roll your own and you'd eventually leak a session or botch a password reset. Reach for Passport.js and you'd be back in 2014, callbacks and all. Pick NextAuth and you were quietly marrying yourself to Next.js. Love Lucia? Great, but it was low-level, and then it got sunset. Want it all handled? A SaaS would happily do it, for a bill that grows with every user you add.

Every option asked you to give something up: your framework, your data, your money, or your weekend.

Then Better Auth showed up, and in barely a year it did something none of them managed, it became the default. Not "a good option." The default. The thing people reach for without thinking, the thing that quietly ate the rest of the ecosystem. Let's talk about how.

🔐

Quick definition for anyone new to it: Better Auth is a framework-agnostic, TypeScript-first authentication and authorization library. You self-host it, it works with your own database, and it extends through plugins. Keep those four words in mind, they explain almost everything about why it won.

First, The Mess It Walked Into#

To understand why Better Auth landed so hard, you have to remember how fragmented JS auth was. Each tool solved one slice and left you holding the rest:

  • Passport.js — the old guard. Express-only in spirit, strategy soup, no real types, and increasingly unmaintained. It shows its age.
  • NextAuth / Auth.js — genuinely popular, but deeply Next-flavoured. The moment you stepped outside Next.js, or wanted real control over sessions and your database, it fought you.
  • Lucia — a beautiful, low-level library that taught a generation how sessions actually work. But it was deliberately un-batteries-included, and in 2025 its author wound it down into a learning resource rather than a maintained library.
  • Clerk / Auth0 / Supabase Auth — fully managed and lovely to start with, until the per-user pricing, the vendor lock-in, and the "your users live on someone else's servers" reality caught up with you at scale.

So the landscape was: too old, too coupled, too low-level, or too expensive. There was a giant, obvious hole in the middle, a library that was modern, worked everywhere, let you own your data, and didn't charge rent. Better Auth walked straight into it.

1. Framework Agnostic: The Killer Feature#

This is the big one. Better Auth is not "auth for Next.js." It is auth for JavaScript, full stop. Next.js, Nuxt, SvelteKit, SolidStart, Astro, Hono, Express, TanStack Start, it plugs into all of them, because at its core it speaks plain web-standard requests, not framework-specific magic.

Why does this matter so much? Because it decouples your auth choice from your framework choice. You are no longer picking a framework and inheriting its auth story. You learn Better Auth once, and you carry that knowledge to every project regardless of the stack. For teams that ship across multiple frameworks, that is worth its weight in gold, one mental model, everywhere.

NextAuth's Next-centricity was its ceiling. Better Auth simply refused to have one.

Better Auth vs Auth.js vs Auth0: Which One Should You Choose?

A clear comparison of Better Auth, Auth.js, and Auth0. Learn the benefits of each, when to use which, and how they differ in pricing, control, and developer experience.

Read Full Post
Better Auth vs Auth.js vs Auth0: Which One Should You Choose?

2. You Own Your Data (and Your Bill)#

Better Auth is self-hosted and talks directly to your database through adapters, Drizzle, Prisma, Kysely, or a direct connection. Your users, sessions and accounts live in your tables, right next to the rest of your app data.

That single decision quietly solves a pile of problems:

  • No vendor lock-in. Your auth data isn't trapped in someone else's platform. It's just rows in your database.
  • No per-user pricing. Ten users or ten million, the cost is your own infrastructure, not a bill that scales with your success. This alone is why so many teams migrated off SaaS auth.
  • Real joins. Because the user table is in your database, you can join against it like any other data. No syncing users from an external service, no webhook gymnastics to keep two systems in agreement.

Owning your auth data used to mean rolling your own and accepting the risk. Better Auth gives you ownership without the footguns.

3. The Plugin Architecture: Grow Without Ejecting#

Here is where Better Auth turns a "login library" into an auth platform. The core is small, and everything beyond email-and-password is a plugin you opt into:

  • Two-factor auth, passkeys / WebAuthn, magic links, one-time passwords
  • Social and OAuth providers, and even turning your app into an OIDC provider
  • Organizations, multi-tenancy, roles and permissions
  • Admin controls, rate limiting, and more

The genius is that you start tiny and grow by adding a line, not by ejecting or rewriting. With the old libraries, "add 2FA" or "add organizations" often meant bolting on a second system and wiring it together yourself. Here it's one plugin in the config, fully typed, sharing the same database and session.

🧩

Plugins are why teams don't outgrow Better Auth. Most auth libraries handle the happy path and abandon you at the first "enterprise" requirement, SSO, orgs, audit. Better Auth's answer to "can it do X?" is almost always "yes, there's a plugin," and you never had to leave the ecosystem to get it.

4. End-to-End Type Safety and a DX That Just Feels Right#

Better Auth is TypeScript-first, not TypeScript-tolerant. You define your config on the server, and the client is fully typed from it, the plugins you enable literally change the shape of your client API. Enable the organization plugin and authClient.organization appears, typed and ready. Autocomplete guides you the whole way.

The developer experience is the quiet reason it spreads by word of mouth. A clean server/client split, sensible defaults, hooks for the lifecycle events you care about, and very little ceremony to get from zero to a working login. It's the rare library where the docs example basically is your production setup.

5. It Does Authorization, Not Just Authentication#

Most "auth" libraries actually only do authn, they log a user in and stop. But real apps need authz too: who belongs to which organization, who can do what, what role gates which action. Historically that meant a second library or a hand-rolled permissions layer.

Better Auth folds this in. Organizations, members, roles and access control are first-class (via plugins), sharing the same session and data model as your login. "Log the user in" and "check if this user can delete that resource" live in one coherent system instead of two that you have to keep in sync. For SaaS products, that's not a nice-to-have, it's the whole ballgame.

6. Timing: It Filled the Vacuum Perfectly#

Great tools also need great timing, and Better Auth's was impeccable. It arrived right as Lucia wound down, leaving a wave of developers who wanted its "own your sessions" philosophy but with batteries included. It arrived as NextAuth frustration over framework coupling was peaking. And it arrived as teams were doing the math on SaaS auth pricing and not liking the answer.

It didn't just build a good library, it built the exact library a frustrated ecosystem was already reaching for. Momentum did the rest.

Next.Js authentication using Lucia and MongoDB

Lucia is an auth library for server that abstracts away the complexity of handling sessions. Fully typed and strong support of database out of the box with built in adapters for ORM

Read Full Post
Next.Js authentication using Lucia and MongoDB

A Quick Taste of How Little It Takes#

Talk is cheap, here's roughly what a real setup looks like. Server side, you configure once:

ts
// auth.ts
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { twoFactor, organization, passkey } from 'better-auth/plugins';
import { db } from './db';
 
export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: 'pg' }),
  emailAndPassword: { enabled: true },
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    },
  },
  // grow by adding a line, not by ejecting
  plugins: [twoFactor(), passkey(), organization()],
});

And the client is inferred from that config, fully typed:

ts
// auth-client.ts
import { createAuthClient } from 'better-auth/react';
 
export const authClient = createAuthClient();
 
// usage, all type-safe
await authClient.signIn.email({ email, password });
await authClient.signIn.social({ provider: 'github' });
await authClient.signIn.passkey();

That's email/password, GitHub OAuth, 2FA, passkeys and organizations, in a handful of lines, backed by your own database, with the client typed off your server config. That density is the whole pitch.

The Honest Caveats#

I'm not here to sell you a miracle, so a couple of fair points:

  • It's young and moving fast. A fast-moving library means occasional breaking changes and APIs that are still settling. Pin your versions and read the release notes.
  • Self-hosting is a responsibility. Owning your data means owning the ops, backups, migrations, and the security of your own setup. SaaS auth exists precisely because some teams would rather pay to not think about this. That's a legitimate trade-off, just make it consciously.

Neither of these dents the core thesis. They're the price of control, and for most teams it's a price well worth paying.

Conclusion#

Better Auth didn't win by having one flashy feature. It won by refusing every compromise the incumbents forced on you. It's framework agnostic, so it doesn't marry you to a stack. You own your data, so there's no lock-in and no per-user tax. It has a plugin architecture, so you grow without ejecting. It's type-safe and a joy to use, so it spreads by word of mouth. And it does authorization, not just login, so real apps don't outgrow it.

Put simply, it's what you'd build if you sat down today, knowing everything the last decade of JS auth taught us. That's why it went from new to default so fast, and why, when someone asks me what to use for auth now, I barely have to think about the answer.

If you've migrated to Better Auth, or you're weighing it up, I'd love to hear how it's gone, drop a comment below. Happy building! 🔐🚀

Comments (0)

Keep Reading

Related Posts