I used to reach for NextAuth on every project by default.

Then I built a few dashboards where I needed full control over the token — custom claims, a specific cookie strategy, no extra abstraction layer to fight with. Rolling my own JWT auth turned out simpler than expected, and it's what I use now unless a client specifically wants OAuth providers out of the box.

Here's the exact setup.

1. The Auth Helpers

// lib/auth.ts