npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

better-auth-firebase-auth

v2.1.0

Published

Use Firebase Authentication (Phone, Google, Email) with Better Auth sessions, plugins, and organizations

Downloads

891

Readme

better-auth-firebase-auth

npm version CI License: MIT

Use Firebase Authentication — Phone, Google, Email/Password — while Better Auth owns sessions, organizations, plugins, and roles.

  • Install: pnpm add better-auth-firebase-auth firebase-admin firebase better-auth

Why Firebase Auth with Better Auth?

Firebase Authentication is a battle-tested identity platform. Better Auth is a comprehensive session and user management framework for TypeScript apps. This plugin bridges them:

  • Firebase verifies identity and handles SMS OTP, OAuth flows, and password emails.
  • Better Auth creates and manages sessions, organizations, roles, API keys, and plugins.
  • No Twilio account needed for phone auth — Firebase handles SMS delivery globally.
  • No email provider setup needed — Firebase handles password reset and verification emails.
Firebase Auth                           Better Auth
─────────────────                       ──────────────────────
Phone OTP (SMS)  ──┐                    Sessions
Google OAuth     ──┼── Firebase ID  ──► Users
Email/Password   ──┘    Token           Organizations
                                        Plugins
                                        Roles

Supported Authentication Methods

Currently Supported

  • Phone Authentication — Firebase sends/verifies SMS OTP, plugin creates the Better Auth session (signInWithPhone)
  • Google Sign-In — OAuth via Firebase (signInWithGoogle)
  • Email/Password — sign in, sign up, password reset (signInWithEmail)

Not Yet Supported

Social providers (Facebook, GitHub, Twitter/X, Microsoft, Apple, LinkedIn), anonymous auth, SAML/OIDC, MFA, and custom tokens. Contributions welcome — see Contributing.


Installation

# npm
npm install better-auth-firebase-auth firebase-admin firebase better-auth

# pnpm
pnpm add better-auth-firebase-auth firebase-admin firebase better-auth

# yarn
yarn add better-auth-firebase-auth firebase-admin firebase better-auth

# bun
bun add better-auth-firebase-auth firebase-admin firebase better-auth

Import Paths

The package exposes separate entry points so bundlers never mix server-only firebase-admin into client bundles:

// Server: API routes, server components, server actions
import { firebaseAuthPlugin } from "better-auth-firebase-auth/server";

// Client: React components, browser code
import { firebaseAuthClientPlugin } from "better-auth-firebase-auth/client";

// Main entry (backward compat — prefer specific paths above)
import { firebaseAuthPlugin, firebaseAuthClientPlugin } from "better-auth-firebase-auth";

Setup

Server (lib/auth.ts):

import { betterAuth } from "better-auth";
import { firebaseAuthPlugin } from "better-auth-firebase-auth/server";
import { getAuth } from "firebase-admin/auth";

export const auth = betterAuth({
  plugins: [
    firebaseAuthPlugin({
      useClientSideTokens: true,
      firebaseAdminAuth: getAuth(),
    }),
  ],
});

Client (lib/auth-client.ts):

import { createAuthClient } from "better-auth/react";
import { firebaseAuthClientPlugin } from "better-auth-firebase-auth/client";

export const authClient = createAuthClient({
  plugins: [firebaseAuthClientPlugin()],
});

Firebase Phone Authentication with Better Auth

Firebase Phone Auth works without Twilio or any third-party SMS provider. Firebase handles delivery globally; this plugin bridges the verified Firebase ID token into a Better Auth session.

Flow

1. User enters phone number
2. Firebase sends SMS OTP (reCAPTCHA verified)
3. User enters OTP → Firebase issues ID token
4. Client sends ID token to this plugin
5. Plugin verifies token with Firebase Admin SDK
6. Plugin creates / links Better Auth user and session

Client-side (React / Next.js)

import {
  getAuth,
  RecaptchaVerifier,
  signInWithPhoneNumber,
} from "firebase/auth";
import { authClient } from "@/lib/auth-client";

const firebaseAuth = getAuth();

// Step 1: Set up reCAPTCHA and send OTP
const verifier = new RecaptchaVerifier(firebaseAuth, "recaptcha-container", {
  size: "invisible",
});
const confirmation = await signInWithPhoneNumber(
  firebaseAuth,
  "+15555550100",
  verifier,
);

// Step 2: Confirm OTP and exchange for Better Auth session
const result = await confirmation.confirm("123456"); // OTP from SMS
const idToken = await result.user.getIdToken();

await authClient.signInWithPhone({ idToken });
// Better Auth session cookie is now set

Server-side plugin config

No extra options are required for phone auth beyond the basic setup. Optionally customize how synthetic emails are generated for phone-only users (users with no email on their Firebase account):

firebaseAuthPlugin({
  firebaseAdminAuth: getAuth(),
  getPhoneUserFallbackEmail: ({ uid, phoneNumber }) =>
    `${uid}@phone.myapp.com`, // defaults to `${uid}@firebase.local`
})

Firebase Console setup for Phone Auth

  1. Open Firebase Console → your project → AuthenticationSign-in method
  2. Enable Phone provider and click Save
  3. For production, add your domain to Authorized domains under AuthenticationSettings
  4. For development, add test phone numbers under PhonePhone numbers for testing (avoids real SMS)

Google Sign-In

import { getAuth, GoogleAuthProvider, signInWithPopup } from "firebase/auth";

const provider = new GoogleAuthProvider();
const result = await signInWithPopup(getAuth(), provider);
const idToken = await result.user.getIdToken();

await authClient.signInWithGoogle({ idToken });

Email/Password Authentication

Client-side token mode (default)

Sign in with Firebase client SDK, then exchange the token:

import { getAuth, signInWithEmailAndPassword } from "firebase/auth";

const credential = await signInWithEmailAndPassword(
  getAuth(),
  "[email protected]",
  "password",
);
const idToken = await credential.user.getIdToken();

await authClient.signInWithEmail({ idToken });

Server-side token mode

Pass credentials directly — the server handles Firebase client SDK:

firebaseAuthPlugin({
  useClientSideTokens: false,
  firebaseAdminAuth: getAuth(),
  firebaseConfig: {
    apiKey: process.env.FIREBASE_API_KEY!,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN!,
    projectId: process.env.FIREBASE_PROJECT_ID!,
  },
})
await authClient.signInWithEmail({
  email: "[email protected]",
  password: "password",
});

Override Better Auth email/password flow

Route Better Auth's built-in /sign-in/email and /sign-up/email through Firebase (requires firebaseConfig):

firebaseAuthPlugin({
  overrideEmailPasswordFlow: true,
  firebaseConfig: { ... },
  firebaseAdminAuth: getAuth(),
})

Password Reset

Firebase handles the email delivery. No email provider setup required.

Plugin config

firebaseAuthPlugin({
  firebaseConfig: {
    apiKey: process.env.FIREBASE_API_KEY!,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN!,
    projectId: process.env.FIREBASE_PROJECT_ID!,
  },
  passwordResetUrl: "https://myapp.com/reset-password", // optional custom page
})

Reset flow

// 1. Send reset email
await authClient.sendPasswordReset({ email: "[email protected]" });

// 2. On the reset page, extract the code Firebase appended to the URL
import { extractOobCodeFromUrl } from "better-auth-firebase-auth/client";
const oobCode = extractOobCodeFromUrl(); // reads ?oobCode= from current URL

// 3. Optionally verify the code and pre-fill the email
const { email } = await authClient.verifyPasswordResetCode({ oobCode });

// 4. Confirm the new password
await authClient.confirmPasswordReset({ oobCode, newPassword: "newpass123" });

Firebase Console setup for password reset

  1. Enable Email/Password in AuthenticationSign-in method
  2. Add your domain to AuthenticationSettingsAuthorized domains (required for custom passwordResetUrl)
  3. Optionally customize templates in AuthenticationTemplatesPassword reset

Server-side only mode

When serverSideOnly: true, no endpoints are registered. Auth happens entirely through hooks that intercept Better Auth routes:

firebaseAuthPlugin({
  serverSideOnly: true,
  overrideEmailPasswordFlow: true,
  firebaseConfig: { ... },
  firebaseAdminAuth: getAuth(),
})

Options

| Option | Type | Default | Description | |---|---|---|---| | useClientSideTokens | boolean | true | Client obtains Firebase token; server only verifies. | | overrideEmailPasswordFlow | boolean | false | Intercept Better Auth email routes and route through Firebase. | | serverSideOnly | boolean | false | Register no endpoints; use hooks only. | | firebaseAdminAuth | Auth | getAuth() | Firebase Admin Auth instance. | | firebaseConfig | FirebaseOptions | — | Required for server-side mode, password reset, and overrideEmailPasswordFlow. | | sessionExpiresInDays | number | 7 | Better Auth session lifetime. | | passwordResetUrl | string | — | Custom URL Firebase appends the reset code to. | | getPhoneUserFallbackEmail | ({ uid, phoneNumber }) => string | ${uid}@firebase.local | Generate a stable synthetic email for phone-only users. |


Better Auth Compatibility

  • Better Auth v1.5+: createAuthMiddleware from better-auth/api (preferred)
  • Older releases: falls back to better-auth/plugins

FAQ

What is better-auth-firebase-auth?

A Better Auth plugin that bridges Firebase Authentication identities into Better Auth sessions. Firebase verifies identity; Better Auth manages sessions, users, organizations, and plugins.

Does this support Firebase Phone Authentication?

Yes. Phone Auth is a first-class supported method as of v0.2. Firebase handles SMS OTP verification and issues a signed ID token; this plugin verifies that token and creates the Better Auth session. No Twilio or external SMS provider is needed.

How is Firebase Phone Auth with Better Auth different from Better Auth's built-in phone plugin?

Better Auth's phoneNumber plugin manages the OTP lifecycle itself (requires an SMS provider like Twilio). This plugin delegates OTP to Firebase — Google manages SMS delivery, reCAPTCHA, rate limiting, and fraud prevention. Use this plugin when you are already on Firebase or want to avoid setting up a separate SMS provider.

Does this plugin support Google Sign-In and email/password?

Yes. Google Sign-In, email/password, and phone are all supported. Password reset uses Firebase email delivery — no separate email provider setup required.

Should I use client-side or server-side token generation?

Use useClientSideTokens: true (default) for the simplest setup. Use false when you want the server to own Firebase client initialization.

Can I use this with Next.js?

Yes. Use better-auth-firebase-auth/server in server code and better-auth-firebase-auth/client in browser/client code to avoid bundling Firebase Admin into the client bundle.

Does this plugin override Better Auth email/password by default?

No. Set overrideEmailPasswordFlow: true to opt in.


Example Project

See the minimal Next.js example for a complete working setup including Google Sign-In and email/password. The example README explains build-time defaults so next build works without a full .env.


Firestore Adapter

To store Better Auth data in Firestore, use @yultyyev/better-auth-firestore:

import { firestoreAdapter } from "@yultyyev/better-auth-firestore";

export const auth = betterAuth({
  database: firestoreAdapter(),
  plugins: [firebaseAuthPlugin({ ... })],
});

Contributing

Contributions are welcome. Please follow the Better Auth Contributing Guide for development setup and code style.

License

MIT