Passport.js
The original Node.js authentication middleware — 500+ strategies
Overview
Passport.js is the original authentication middleware for Node.js, released in 2011. It introduced the strategy pattern for authentication — each provider (local, OAuth, SAML, LDAP) is a separate pluggable strategy. With 500+ strategies available, it covers virtually every auth scenario.
Passport doesn't prescribe sessions or token management — it integrates with Express session middleware (express-session) or sets a req.user after validation, leaving the rest to you. This makes it extremely flexible but requires wiring up several pieces yourself.
Despite being over a decade old, Passport remains the dominant choice for Express and Fastify applications. The ecosystem of strategies for enterprise protocols (SAML, LDAP, Kerberos) is unmatched.
Architecture fit
Best suited to run inside your main application process alongside your app logic and database.
Key features
Trade-offs
Largest strategy ecosystem — covers SAML, LDAP, Kerberos, OIDC
Callback-heavy API design — predates async/await
Battle-tested since 2011, extremely stable
Wires multiple packages — passport + session + strategy
Framework-agnostic (Express, Fastify, Koa)
Not designed for Next.js App Router or Edge runtime
Best choice for enterprise SSO in Node.js backends
No built-in UI, organizations, or modern auth primitives
✓ When to use
- →Express or Fastify REST APIs
- →Enterprise SAML/LDAP/Kerberos SSO requirements
- →Migrating a legacy Node.js app with existing Passport setup
- →Need a specific strategy that only Passport has
✗ When NOT to use
- →New Next.js projects — Auth.js, Better Auth, or Clerk are better fits
- →Edge runtime or serverless (Passport needs Node.js APIs)
- →Apps that need organizations, API keys, or passkeys built-in
Implementation
TypeScript// Express setup with local + GitHub strategies
import passport from "passport";
import { Strategy as LocalStrategy } from "passport-local";
import { Strategy as GitHubStrategy } from "passport-github2";
import session from "express-session";
// Session serialization
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser(async (id, done) => {
const user = await db.user.findUnique({ where: { id } });
done(null, user);
});
// Local strategy (email + password)
passport.use(new LocalStrategy({ usernameField: "email" },
async (email, password, done) => {
const user = await db.user.findUnique({ where: { email } });
if (!user || !await bcrypt.compare(password, user.passwordHash))
return done(null, false, { message: "Invalid credentials" });
return done(null, user);
}
));
// GitHub OAuth strategy
passport.use(new GitHubStrategy(
{ clientID: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET!, callbackURL: "/auth/github/callback" },
async (accessToken, refreshToken, profile, done) => {
const user = await db.user.upsert({
where: { githubId: profile.id },
create: { githubId: profile.id, email: profile.emails?.[0].value },
update: {},
});
return done(null, user);
}
));
// Middleware wiring
app.use(session({ secret: process.env.SESSION_SECRET!, resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
// Routes
app.post("/auth/login", passport.authenticate("local", { successRedirect: "/", failureRedirect: "/login" }));
app.get("/auth/github", passport.authenticate("github", { scope: ["user:email"] }));
app.get("/auth/github/callback", passport.authenticate("github", { successRedirect: "/" }));
// Protect a route
app.get("/dashboard", (req, res) => {
if (!req.isAuthenticated()) return res.redirect("/login");
res.json({ user: req.user });
});In production
Uses Passport's OAuth strategies in their developer ecosystem APIs
Dominant auth solution for Express apps, used by hundreds of thousands of Node.js projects
Other frameworks
Better Auth
TypeScript-first, self-hosted authentication with full schema ownership
Auth.js (NextAuth v5)
The most popular authentication library for Next.js and the JS ecosystem
Clerk
Managed authentication with prebuilt UI components — zero infrastructure
Lucia
Minimal session management primitives — you control the auth logic