Das Edge-Problem & die Split-Config

Sobald du einen Datenbank-Adapter (Prisma, Drizzle, …) für Database-Sessions einsetzt, kann deine Middleware kaputtgehen — mit kryptischen Fehlern über fehlende Node-Module. Der Grund: Middleware läuft auf der Edge-Runtime, und viele DB-Treiber tun das nicht. Die Lösung heißt Split-Config.

Die Diagnose in einem Satz: Middleware = Edge-Runtime. DB-Adapter = oft nur Node-Runtime. Lädt deine Middleware die volle auth.ts mitsamt Adapter, zieht sie damit Node-only-Code in die Edge — und es knallt beim Build oder zur Laufzeit.

Warum überhaupt Edge?

  • Middleware läuft vor jeder passenden Anfrage, möglichst nah am Nutzer — dafür eine schlanke, schnelle Runtime ohne das volle Node-API.
  • Datenbank-Treiber brauchen aber oft genau dieses Node-API (TCP-Sockets, crypto, native Bindings).
  • Folge: Der Adapter darf nicht in den Edge-Bundle — die Middleware darf nur den edge-sicheren Teil der Config sehen.

Die Lösung: Config aufteilen

Du trennst die Konfiguration in einen edge-sicheren Kern (Provider + Callbacks, kein Adapter) und die volle Config (Kern + Adapter). Die Middleware nutzt nur den Kern.

auth.config.ts — edge-sicher, kein Adapter
import GitHub from "next-auth/providers/github";
import type { NextAuthConfig } from "next-auth";

export default {
  providers: [GitHub],
  callbacks: {
    authorized({ request, auth }) {
      const aufDashboard =
        request.nextUrl.pathname.startsWith("/dashboard");
      return aufDashboard ? !!auth?.user : true;
    },
  },
} satisfies NextAuthConfig;
auth.ts — volle Config mit Adapter (Node-Runtime)
import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/lib/prisma";
import authConfig from "./auth.config";

export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },
  ...authConfig,
});
middleware.ts — nur der edge-sichere Kern
import NextAuth from "next-auth";
import authConfig from "./auth.config";

export const { auth: middleware } = NextAuth(authConfig);

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
Warum eigentlich?Warum strategy: jwt beim Adapter?
Mit einem DB-Adapter wäre die Default-Session-Strategie database — jeder Session-Lookup ginge dann gegen die DB. Genau das kann die Edge-Middleware aber nicht. Setzt du session.strategy: "jwt", lebt die Session im signierten Cookie, und die Middleware kann sie ohne DB-Zugriff verifizieren — der Adapter bleibt nur für persistente Daten (User-Tabelle, verknüpfte Accounts) zuständig.
Häufiger DenkfehlerFehler: Module not found (net / dns / fs) in der Middleware
Dieser Fehler ist die Signatur des Edge-Problems: Ein Node-only-Modul (vom DB-Treiber) ist über die volle auth.ts in den Edge-Bundle gerutscht. Fast immer die Ursache: Die Middleware importiert @/auth statt auth.config. Lass die Middleware nur den edge-sicheren Kern laden, dann verschwindet der Fehler.
Tiefer reinBrauche ich die Split-Config immer?
Nein. Ohne DB-Adapter — also reine JWT-Sessions, Credentials oder nur OAuth ohne Persistenz — funktioniert eine einzige auth.ts problemlos in der Middleware. Die Aufteilung lohnt sich genau dann, wenn ein nicht-edge-fähiger Adapter ins Spiel kommt. Im Zweifel: erst einfach halten, splitten sobald der erste Edge-Fehler auftaucht.