Authentication Patterns: JWT vs. Managed Auth
When to roll your own JWT auth and when to reach for a managed provider like Clerk — with the trade-offs I weigh on every project.
Auth is the part of an app you cannot afford to get subtly wrong. Here's how I decide between hand-rolled JWT and a managed provider.
The JWT approach
For full control and zero external dependencies, JWT access/refresh tokens with route guards are hard to beat.
import jwt from "jsonwebtoken";
export function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(" ")[1];
if (!token) return res.status(401).json({ error: "Unauthorized" });
try {
req.user = jwt.verify(token, process.env.JWT_SECRET!);
next();
} catch {
res.status(401).json({ error: "Invalid token" });
}
}The cost: you own refresh rotation, password resets, email verification, and session revocation. That's real surface area to secure.
When I reach for Clerk
For products that need social login, MFA, and a polished account UI yesterday, a managed provider removes weeks of work and an entire class of security bugs.
| Concern | Hand-rolled JWT | Managed (Clerk) |
|---|---|---|
| Control | Total | Constrained |
| Time to ship | Slow | Fast |
| Security scope | Yours | Theirs |
My rule of thumb
If auth is the product (a security tool, a custom SSO), own it. If auth is table stakes, use a provider and spend your time on the thing that's actually differentiated.