Die Authentifizierung ist der Grundstein jeder modernen Webanwendung, doch ihre Einrichtung bleibt eine der zeitaufwändigsten Herausforderungen, denen Entwickler gegenüberstehen. Hier kommt Better Auth API ins Spiel – eine Framework-agnostische Authentifizierungslösung, die verspricht, die Art und Weise, wie wir die Benutzerverwaltung implementieren, zu transformieren. In diesem umfassenden Leitfaden werden wir eine vollständige Full-Stack-Anwendung erstellen, die die Leistungsfähigkeit und Einfachheit von Better Auth demonstriert, wobei wir Bun für eine blitzschnelle Performance nutzen.
Möchten Sie eine integrierte All-in-One-Plattform für Ihr Entwicklerteam, um mit maximaler Produktivität zusammenzuarbeiten?
Apidog erfüllt all Ihre Anforderungen und ersetzt Postman zu einem viel günstigeren Preis!
Was ist Better Auth API?
Better Auth API ist ein modernes, quelloffenes Authentifizierungs-Framework, das nahtlos in jeder JavaScript-Umgebung funktioniert. Im Gegensatz zu traditionellen Authentifizierungsbibliotheken, die Sie an spezifische Ökosysteme binden, bietet Better Auth eine einheitliche API, die sich an Ihren Stack anpasst – egal, ob Sie React, Vue, Svelte oder Vanilla JavaScript im Frontend und Node.js, Bun oder Deno im Backend verwenden. Seine Plugin-basierte Architektur unterstützt mehrere Authentifizierungsstrategien, von traditioneller E-Mail/Passwort bis hin zu OAuth-Anbietern, Passkeys und Magic Links, während gleichzeitig Typensicherheit und eine exzellente Entwicklererfahrung gewährleistet werden.

Erste Schritte mit Better Auth: Voraussetzungen und Projekteinrichtung
Bevor Sie in den Code eintauchen, stellen Sie sicher, dass Folgendes installiert ist:
- Bun 1.0+: Wir werden Bun in diesem Tutorial für seine außergewöhnliche Geschwindigkeit und modernen Tools verwenden.
- Node.js 18+: Für die Backend-Laufzeitumgebung erforderlich.
- Ein Code-Editor: VS Code wird für TypeScript-Unterstützung empfohlen.

Obwohl dieses Setup perfekt mit npm funktioniert, werden wir den Bun-Workflow demonstrieren, der eine 3-5x schnellere Paketinstallation und ein optimierteres Entwicklungserlebnis bietet.
Erstellen eines Beispielprojekts: Schritt-für-Schritt-Implementierung
Lassen Sie uns ein praktisches Authentifizierungssystem mit einem React-Frontend und einem Express-Backend erstellen, komplett mit Datenbankpersistenz.
Schritt 1: Backend-Einrichtung mit Express und Drizzle ORM
1. Backend-Projekt initialisieren
Erstellen Sie zuerst Ihr Backend-Verzeichnis und wechseln Sie dorthin:
mkdir better-auth-backend
cd better-auth-backend
bun init -y
2. Abhängigkeiten installieren
Wir benötigen Express für den Server, Better Auth für die Authentifizierung und Drizzle ORM für die Datenbankverwaltung:
bun add express better-auth drizzle-orm
bun add -D @types/bun @types/express drizzle-kit
3. Umgebungsvariablen konfigurieren
Erstellen Sie eine .env-Datei, um sensible Konfigurationen zu speichern:
BETTER_AUTH_SECRET=your-secret-key-here # Generieren mit: openssl rand -base64 32
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=local.db
Der BETTER_AUTH_SECRET kann auch auf der Better-Auth-Website generiert werden.
4. Datenbankschema mit Drizzle ORM erstellen
Better Auth funktioniert am besten mit Drizzle, das eine hervorragende TypeScript-Unterstützung bietet und Probleme mit nativen Modulen vermeidet. Erstellen Sie src/db/schema.ts:
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
export const user = sqliteTable("user", {
id: text("id").primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: integer('email_verified', { mode: 'boolean' }).notNull().default(false),
image: text('image'),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
});
export const session = sqliteTable("session", {
id: text("id").primaryKey(),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
token: text('token').notNull().unique(),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
userId: text('user_id').notNull(),
});
export const account = sqliteTable("account", {
id: text("id").primaryKey(),
accountId: text('account_id').notNull(),
providerId: text('provider_id').notNull(),
userId: text('user_id').notNull(),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
});
export const verification = sqliteTable("verification", {
id: text("id").primaryKey(),
identifier: text('identifier').notNull(),
value: text('value').notNull(),
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
});
5. Datenbankverbindung konfigurieren
Erstellen Sie src/db/index.ts unter Verwendung von Buns nativem SQLite-Binding:
import { Database } from "bun:sqlite";
import { drizzle } from "drizzle-orm/bun-sqlite";
const sqlite = new Database("local.db");
export const db = drizzle(sqlite);
6. Better Auth Konfiguration einrichten
Erstellen Sie src/lib/auth.ts, um die Better Auth API zu konfigurieren:
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "../db";
import { user, session, account, verification } from "../db/schema";
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "sqlite",
schema: {
user: user,
session: session,
account: account,
verification: verification,
},
}),
emailAndPassword: {
enabled: true,
},
trustedOrigins: ["http://localhost:5173"],
});
7. Express-Server erstellen
In src/index.ts binden Sie den Better Auth API-Handler ein:
import express from "express";
import cors from "cors";
import { toNodeHandler } from "better-auth/node";
import { auth } from "./lib/auth";
const app = express();
const PORT = process.env.PORT || 3000;
app.use(
cors({
origin: "http://localhost:5173",
credentials: true,
})
);
// Mount Better Auth API at /api/auth
app.use("/api/auth", toNodeHandler(auth));
app.use(express.json());
app.get("/api/me", async (req, res) => {
const session = await auth.api.getSession({
headers: req.headers,
});
if (!session) {
return res.status(401).json({ error: "Unauthorized" });
}
res.json({ user: session.user });
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
8. Datenbankmigration ausführen
Erstellen Sie drizzle.config.ts im Backend-Stammverzeichnis:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
dialect: "sqlite",
schema: "./src/db/schema.ts",
out: "./drizzle",
dbCredentials: {
url: "local.db",
},
});
Führen Sie die Migration aus, um Tabellen zu erstellen:
bunx drizzle-kit push

Schritt 2: Frontend-Einrichtung mit React und Vite
1. React-Anwendung erstellen
Initialisieren Sie in einem neuen Terminal das Frontend:
bun create vite better-auth-frontend --template react-ts
cd better-auth-frontend
2. Abhängigkeiten installieren
bun add better-auth
3. Tailwind CSS konfigurieren (V4 Update)
Nach Tailwind CSS v4 ist eine andere Einrichtung erforderlich. Installieren Sie die neuen Pakete:
bun add -D tailwindcss postcss @tailwindcss/postcss
Erstellen Sie tailwind.config.js im Projektstammverzeichnis:
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Erstellen Sie postcss.config.js:
export default {
plugins: {
"@tailwindcss/postcss": {},
},
}
Erstellen Sie src/index.css:
@import "tailwindcss";
body {
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
}
4. Better Auth Client einrichten
Erstellen Sie src/lib/auth-client.ts:
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
baseURL: "http://localhost:3000",
});
export const { signIn, signUp, useSession } = authClient;
5. Authentifizierungs-UI erstellen
Ersetzen Sie src/App.tsx durch eine vollständige Authentifizierungsoberfläche:
import { useState } from 'react';
import { useSession, signIn, signUp } from './lib/auth-client';
function App() {
const { data: session, isPending } = useSession();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [name, setName] = useState('');
const handleSignUp = async (e: React.FormEvent) => {
e.preventDefault();
await signUp.email({
name,
email,
password,
callbackURL: '/',
});
};
const handleSignIn = async (e: React.FormEvent) => {
e.preventDefault();
await signIn.email({
email,
password,
});
};
const handleSignOut = async () => {
await authClient.signOut();
};
if (isPending) return <div className="flex items-center justify-center min-h-screen">Wird geladen...</div>;
return (
<div className="min-h-screen bg-gray-100 flex items-center justify-center p-4">
<div className="max-w-md w-full bg-white rounded-lg shadow-md p-6">
<h1 className="text-2xl font-bold text-center mb-6 text-gray-800">
Better Auth API Test
</h1>
{session?.user ? (
<div className="space-y-4">
<div className="bg-green-50 p-4 rounded-md">
<p className="text-green-800 font-semibold">Angemeldet als:</p>
<p className="text-green-700">{session.user.email}</p>
<p className="text-green-600 text-sm">{session.user.name}</p>
</div>
<button
onClick={handleSignOut}
className="w-full bg-red-500 hover:bg-red-600 text-white font-medium py-2 px-4 rounded-md transition"
>
Abmelden
</button>
</div>
) : (
<div className="space-y-4">
<form onSubmit={handleSignUp} className="space-y-3">
<h2 className="text-lg font-semibold text-gray-700">Registrieren</h2>
<input
type="text"
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
<input
type="email"
placeholder="E-Mail"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
<input
type="password"
placeholder="Passwort"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
<button
type="submit"
className="w-full bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-md transition"
>
Konto erstellen
</button>
</form>
<form onSubmit={handleSignIn} className="space-y-3">
<h2 className="text-lg font-semibold text-gray-700">Anmelden</h2>
<input
type="email"
placeholder="E-Mail"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
<input
type="password"
placeholder="Passwort"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
<button
type="submit"
className="w-full bg-blue-500 hover:bg-blue-600 text-white font-medium py-2 px-4 rounded-md transition"
>
Anmelden
</button>
</form>
</div>
)}
</div>
</div>
);
}
export default App;

Schritt 3: Integration testen
1. Backend-Server starten
cd better-auth-backend
bun dev

2. Frontend-Entwicklung starten
cd better-auth-frontend
bun dev

3. Authentifizierungsfluss testen
- Öffnen Sie
http://localhost:5173in Ihrem Browser - Registrieren Sie einen neuen Benutzer über das Registrierungsformular


- Beobachten Sie, wie die Datenbankdatei wächst, während Tabellen gefüllt werden
- Melden Sie sich ab und wieder an, um die Sitzungsverwaltung zu überprüfen
- Überprüfen Sie den Sitzungsendpunkt:
http://localhost:3000/api/auth/session

Hauptvorteile der Better Auth API
Die Better Auth API zeichnet sich durch mehrere überzeugende Vorteile aus:
- Framework-Agnostizismus: Im Gegensatz zu NextAuth.js oder Firebase Auth funktioniert Better Auth überall dort, wo JavaScript läuft. Dieselbe Authentifizierungslogik dient Web-, Mobil- und API-Clients ohne Änderungen.
- Mehrere Authentifizierungsstrategien: Sofortige Unterstützung für Anmeldeinformationen, OAuth 2.0, Passkeys, Zwei-Faktor-Authentifizierung und Magic Links. Jede Strategie ist ein Plugin, das mit einer einzigen Konfigurationszeile aktiviert werden kann.
- Typensicherheit: Volle TypeScript-Unterstützung mit abgeleiteten Typen aus Ihrem Datenbankschema eliminiert das "any"-Typen-Chaos, das in Authentifizierungs-Codebasen üblich ist.
- Datenbankflexibilität: Der Drizzle ORM-Adapter bedeutet, dass Sie zwischen SQLite, PostgreSQL und MySQL wechseln können, ohne Ihre Authentifizierungslogik zu ändern. Dieses Tutorial verwendet SQLite der Einfachheit halber, aber derselbe Code skaliert auch auf Produktionsdatenbanken.
- Plugin-Ökosystem: Benötigen Sie Organisationsunterstützung? Multi-Tenancy? Admin-Rollen? Das Plugin-System von Better Auth ermöglicht es Ihnen, die Funktionalität zu erweitern, ohne den Kern aufzublähen.
- Performance: Mit Bun als Laufzeitumgebung liegen Kaltstarts unter 100 ms, und der gesamte Authentifizierungsfluss ist auf bescheidener Hardware in unter 50 ms abgeschlossen.
Häufig gestellte Fragen
F1: Kann ich die Better Auth API mit npm anstelle von Bun verwenden?
Antwort: Absolut. Obwohl dieser Leitfaden Bun wegen seiner Leistungsvorteile verwendet, hat jeder Befehl ein npm-Äquivalent. Ersetzen Sie bun add durch npm install, bun dev durch npm run dev und bunx durch npx. Der einzige Bun-spezifische Code ist der bun:sqlite-Import, der für Node.js-Umgebungen durch better-sqlite3 ersetzt werden kann.
F2: Warum brauchten wir Drizzle ORM? Kann Better Auth Tabellen nicht automatisch erstellen?
Antwort: Better Auth folgt dem Prinzip der expliziten Datenbankverwaltung. Drizzle bietet typensichere Migrationen, Schema-Versionierung und verhindert versehentlichen Datenverlust. Der Befehl drizzle-kit push ist eine einmalige Einrichtung, die Ihnen die volle Kontrolle über die Entwicklung Ihrer Datenbank gibt.
F3: Was ist, wenn ich den Fehler "Missing parameter name" erhalte?
Antwort: Dies tritt auf, wenn app.all() mit Wildcards in Express verwendet wird. Die Lösung besteht darin, stattdessen app.use("/api/auth", toNodeHandler(auth)) zu verwenden. Der Handler von Better Auth verwaltet alle Unterrouten intern, sodass Express keine Wildcard-Übereinstimmung benötigt.
F4: Wie füge ich soziale Authentifizierungsanbieter hinzu?
Antwort: Aktivieren Sie OAuth-Plugins in Ihrer Better Auth-Konfiguration. Zum Beispiel, um GitHub hinzuzufügen:
import { betterAuth } from "better-auth";
import { github } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
github({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
})
]
});
F5: Ist die Better Auth API produktionsreif?
Antwort: Ja. Better Auth betreibt die Authentifizierung für mehrere SaaS-Produkte mit Tausenden von Benutzern. Das Framework implementiert sichere Sitzungsverwaltung, CSRF-Schutz und folgt den OWASP-Richtlinien. Überprüfen Sie jedoch immer Ihre spezifische Implementierung und halten Sie die Abhängigkeiten auf dem neuesten Stand.
Fazit
Die Authentifizierung von Grund auf neu zu erstellen, ist mit modernen Lösungen wie der Better Auth API nicht mehr notwendig. In diesem Leitfaden haben wir in wenigen Minuten ein komplettes Authentifizierungssystem erstellt – vom Datenbankschema bis zu den UI-Komponenten! Die Kombination aus der Flexibilität von Better Auth, der Typensicherheit von Drizzle ORM und der Leistung von Bun schafft ein Entwicklererlebnis, das vom Prototyp bis zur Produktion skaliert.
Der Schritt-für-Schritt-Prozess zeigt, dass Authentifizierung, obwohl kritisch, nicht komplex sein muss. Durch die Nutzung der Plugin-Architektur und des Framework-agnostischen Designs von Better Auth können Sie sich auf die Entwicklung von Funktionen konzentrieren, die für Ihre Benutzer wichtig sind, anstatt sich mit Sicherheitsimplementierungen herumzuschlagen.
Egal, ob Sie ein Nebenprojekt oder eine Unternehmensanwendung entwickeln, die Better Auth API bietet die Grundlage für eine sichere, skalierbare Authentifizierung, die sich an Ihre Bedürfnisse anpasst – und nicht umgekehrt.
Möchten Sie eine integrierte All-in-One-Plattform für Ihr Entwicklerteam, um mit maximaler Produktivität zusammenzuarbeiten?
Apidog erfüllt all Ihre Anforderungen und ersetzt Postman zu einem viel günstigeren Preis!
