Documentation
Pure modularity for your authentication engine.
⬢ Jargon Buster
New to backend or auth? Here are some simple explanations for common terms we use.
JWT
"JSON Web Token". Think of it as a secure digital pass. Once a user logs in, they carry this token. The server sees it and knows "Aha! This is User #45."
Adapter
The "plugin" that connects Kroxt to your database. It translates Kroxt's commands into something MongoDB or PostgreSQL understands.
Hashing
Turning a password into a scrambled mess. We NEVER store the actual password. We store the hash and compare it later.
Headless
Kroxt doesn't provide the UI (buttons, forms). You build the "head" (the UI) in React/Vue. Kroxt is the "brain" (the logic).
npx kroxt init
Define your User
Decide what data you want your users to have. Pro Tip: The CLI can now automatically generate this boilerplate for you during npx kroxt init.
export interface MyUser { id: string; email: string; passwordHash: string; role: 'admin' | 'user'; schoolId: string; }
Choose an Adapter
Select the adapter for your database. We support the most popular ORMs natively.
import { createMongoAdapter } from "kroxt/adapters/mongoose"; import { User } from "../models/user.model"; export const authAdapter = createMongoAdapter(User);
Initialize the Engine
Finally, create your auth object with your adapter. This is where you set your JWT secret.
import { createAuth } from "kroxt"; export const auth = createAuth({ adapter: authAdapter, secret: process.env.JWT_SECRET, // Global Security Configurations session: { expires: "15m", refreshExpires: "7d", enforceStrictRevocation: true // Real-time token validation }, rateLimit: { max: 100, // Requests per minute limit windowMs: 60 * 1000 }, ipBlocking: { maxStrikes: 5, // Ban IPs after 5 failed login/refresh attempts blockDurationMs: 15 * 60 * 1000 }, passwordPolicy: { minLength: 6, requireUppercase: true, requireSpecialCharacter: true }, jwt: { payload: (user, type) => { // Sign custom metadata into your JWTs securely if (type === "access") { return { role: user.role, schoolId: user.schoolId }; } return {}; } } });
Advanced Security Infrastructure
Kroxt ships with an enterprise-grade security matrix built entirely into the engine's core. Activate these protections simply by injecting them into your createAuth config.
1. Automatic IP Blocking (Brute-Force Shield)
Automatically drop credential stuffing attacks before they hit your database.
export const auth = createAuth({ // ... ipBlocking: { maxStrikes: 5, // Drop IP after 5 failed login attempts blockDurationMs: 15 * 60 * 1000, // 15 minute IP ban } });
2. Hash-Linked Global Revocation
You no longer need to execute slow schema migrations to track active tokens. Run the built-in DX utility block to change a user's password, which natively permanently kills all hijacked active token states globally.
// Changes the password and instantly lockouts all legacy sessions. await auth.changePassword(userId, "new_secure_password");
3. Strict Access Database Hook
By default, JWT access tokens are stateless for maximum serverless scaling. For heavy admin-level protocols, you can toggle Kroxt to force a database hash validation lookup on incredibly every single route execution.
export const auth = createAuth({ // ... session: { expires: "15m", refreshExpires: "7d", enforceStrictRevocation: true // The real-time kill-switch } });
4. Core Password Policy Engine
Dynamically enforce password strength during signup routines before strings even reach the Argon2 hashing protocol natively.
export const auth = createAuth({ // ... passwordPolicy: { minLength: 6, requireUppercase: true, requireSpecialCharacter: true } });
Comparison
"Comparison is the thief of joy."
Here are the simplified reasons why you should use Kroxt over the ecosystem.
vs Other Auth Libraries
- ⬢ Stack agnostic - Works natively with Express, Fastify, Next.js, Hono, and any generic router.
- ⬢ 100% Schema Control - Use your exact database definitions. No bloated, forced migration tables.
- ⬢ Advanced features built-in - IP blocking and Hash-Linked global token revocation natively.
vs Managed Auth Services
- • Keep your data - Your users remain inside your database, not locked into a third-party platform.
- • No per-user costs - Completely free. Scale indefinitely without worrying about MAU (Monthly Active User) billing limits.
- • Single source of truth - Standard SQL joins between your user authentication states and business logic.
vs Rolling Your Own
- • Security handled - Battle-tested crypto algorithms (Argon2 padding) configured securely out of the gate.
- • Zero-schema Migrations - We solved real-time JWT revocation using native hash fragments so you don't have to build complex blacklists.
- • Focus on your product - Spend time deploying user features, not reinventing brute-force IP throttling mechanisms.
Troubleshooting
Prisma "Unknown argument `name`"
Prisma is strictly typed. If you are sending fields (like name or age) during registration, they MUST exist in schema.prisma or Prisma will reject the insert.
Drizzle Database Locking
If you use SQLite, only one process can write at a time. If you get "database is locked," ensure you don't have multiple instances of your server running in the background.
Path Mismatch: passwordHash
Kroxt expects your database field to be named passwordHash ideally. If you name it password in your DB, you may need a mapping in your adapter setup.