Stop Rewriting Authentication in Node.js — I Built a Devise-Inspired Auth Kit
Source: Dev.to
Every time I start a new Node.js backend, authentication ends up being the most repetitive and fragile part of the project.
No matter the stack, I keep rewriting the same things:
- User registration flows
- Password hashing with bcrypt
- JWT generation and verification
- Role‑based access control
- Database‑specific queries baked into auth logic
Even after years of building APIs, auth still feels like copy‑paste architecture — slightly different each time, never quite right, and tightly coupled to the database or ORM I’m using. That frustration is exactly why I built node-auth-kit.
npm: https://www.npmjs.com/package/node-auth-kit
GitHub: https://github.com/learningyogendra-netizen/node-auth-kit
The “Auth Gap” in the Node.js Ecosystem
The Node.js ecosystem is massive, but authentication usually falls into one of two extremes:
- The DIY Trap – Libraries like Passport.js are powerful but very low‑level, leaving authentication logic scattered across controllers, services, and models.
- The Black Box Trap – Frameworks and SaaS auth providers work fast—until you need to customize a flow, migrate your database, or control your data, at which point you realize you’re locked in.
If you’ve ever worked with Ruby on Rails, you probably miss Devise:
- Strong defaults
- Predictable structure
- Extensible when needed
I wanted that same Devise philosophy, but for Node.js.
Core Idea: Database‑Agnostic by Design
Most Node.js auth tutorials teach you to bake authentication directly into your ORM models (Mongoose, Prisma, etc.). This works—until you need to:
- Test auth in isolation
- Change databases
- Reuse logic across projects
node-auth-kit takes a different approach with an adapter architecture:
- Core engine – Handles auth logic (password rules, JWT, roles, hooks)
- Adapters – Handle database communication
Your authentication logic stays the same regardless of the underlying data store.
What This Looks Like in Practice
Instead of writing controllers, you configure the auth engine:
import {
deviceAuth,
mongooseAdapter,
createAuthRouter,
} from 'node-auth-kit';
deviceAuth
.init({
authType: 'jwt',
signupFields: ['email', 'password'],
defaultRole: 'user',
token: {
accessTokenTtl: '1h',
},
})
.useAdapter(
mongooseAdapter({
userModel: User,
})
);
app.use('/auth', createAuthRouter());
That’s it. You now have:
POST /auth/registerPOST /auth/loginGET /auth/me
Route Protection Without Boilerplate
Protecting routes is just middleware:
import { authenticate, authorize } from 'node-auth-kit';
app.get('/profile', authenticate, (req, res) => {
res.json(req.user);
});
app.get('/admin', authenticate, authorize('admin'), (req, res) => {
res.json({ message: 'Admin access granted' });
});
No duplicated logic.
Lifecycle Hooks (The Underrated Feature)
node-auth-kit supports lifecycle hooks for clean extensibility:
beforeRegisterafterRegisterbeforeLoginafterLogin
Example:
deviceAuth.registerHook('afterRegister', async (user) => {
// send welcome email, log analytics, etc.
});
Why I Open‑Sourced It
Authentication is too critical to live as hidden code in private repos. Every team shouldn’t spend their first 1–2 days rebuilding login systems. node-auth-kit is my attempt to create a shared, opinionated starting point for Node.js authentication.
Current Status & Roadmap
- ✅ JWT authentication
- ✅ Role‑based authorization
- ✅ Adapter‑based DB support
- ✅ Stable Mongoose adapter
- 🚧 Prisma adapter (in progress)
- 🔜 Refresh tokens
- 🔜 Multi‑device sessions
- 🔜 Password reset & email verification
Get Started in Under 60 Seconds
npm i node-auth-kit
npm: https://www.npmjs.com/package/node-auth-kit
GitHub: https://github.com/learningyogendra-netizen/node-auth-kit
If this saves you time, a ⭐ on GitHub really helps the project grow.
Final Thought
Stop rewriting authentication.
Start building your product.