create-express-authkit
v2.1.1
Published
CLI to scaffold a Node.js + Express + MongoDB backend with auth built in
Maintainers
Readme
create-express-authkit
A powerful, production-ready CLI tool to scaffold a Node.js + Express backend with MongoDB and a complete JWT Authentication system — including password reset with email OTP. Get your backend up and running in seconds, not hours.
✨ Features
| Category | What you get |
| --- | --- |
| Language | Choose between JavaScript or TypeScript during setup |
| Framework | Express v5 with a clean MVC architecture |
| Database | MongoDB via Mongoose |
| Authentication | JWT-based auth with Access Token + Refresh Token rotation |
| Password Reset | Full forgot-password flow — OTP via email → verify → reset |
| Validation | Request validation with Zod schemas |
| Email | Nodemailer with Gmail OAuth2 for sending OTP emails |
| Security | bcrypt password hashing, HTTP-only secure cookies, comprehensive rate limiting |
| Rate Limiting | express-rate-limit on every endpoint — dual-strategy (IP-only & email+IP compound key) |
| Error Handling | Global error handler + 404 catch-all pre-configured |
| Dev Experience | node --watch (JS) or tsx watch (TS) for hot-reload during development |
| Modern JS | ESM (type: "module") throughout |
📦 Quick Start
Scaffold a new project instantly with npx — no global install needed:
npx create-express-authkit <project-name>You'll be prompted to choose your language:
? Choose your language: ›
❯ JavaScript
TypeScriptExample:
npx create-express-authkit my-backendAll dependencies are automatically installed during scaffolding.
Next Steps
# 1. Navigate into your project
cd my-backend
# 2. Copy the environment file
cp .env.example .env # macOS / Linux
copy .env.example .env # Windows
# 3. Update .env with your own values (see Environment Variables below)
# 4. Start the dev server
npm run devTypeScript projects also support
npm run buildandnpm startfor production builds.
⚙️ Environment Variables
The generated .env.example includes all required variables:
PORT=8000
# MongoDB
MONGODB_URL=mongodb://127.0.0.1:27017/authentication
# JWT Secrets — replace with strong, unique secrets
ACCESS_JWT_SECRET=your_access_jwt_secret_key
REFRESH_JWT_SECRET=your_refresh_jwt_secret_key
JWT_RESET_PASSWORD_TOKEN_SECRET=your_reset_password_jwt_secret_key
# JWT Expiry
ACCESS_JWT_EXPIRES_IN=15m
REFRESH_JWT_EXPIRES_IN=7d
RESET_PASSWORD_JWT_EXPIRES_IN=15m
# CORS
CORS_ORIGIN=http://localhost:5173
# Email (Nodemailer - Gmail App password)
GOOGLE_APP_PASSWORD=your_google_app_password
[email protected]🔌 API Reference
All auth routes are mounted at /api/v1/users.
| Method | Endpoint | Auth | Rate Limited | Description |
| --- | --- | --- | --- | --- |
| POST | /register | ✗ | ✔ (IP) | Register a new user |
| POST | /login | ✗ | ✔ (IP + Email) | Login and receive tokens |
| DELETE | /logout | ✔ | ✗ | Logout and clear refresh token |
| POST | /refresh-token | ✗ | ✔ (IP) | Rotate access & refresh tokens |
| POST | /forget-password | ✗ | ✔ (Email+IP) | Send a password-reset OTP to email |
| POST | /verify-reset-otp | ✗ | ✔ (Email+IP) | Verify the OTP and receive a reset token |
| POST | /reset-password | ✗ | ✔ (Email+IP) | Reset password using the reset token |
A health-check endpoint is also available:
| Method | Endpoint | Description |
| --- | --- | --- |
| GET | /health | Returns { "status": "ok" } |
Request & Response Examples
Request Body:
{
"username": "johndoe",
"email": "[email protected]",
"password": "securePassword123"
}Success Response (201):
{
"success": true,
"message": "User registered successfully",
"userId": "665f..."
}Request Body:
{
"email": "[email protected]",
"password": "securePassword123"
}Success Response (200):
{
"success": true,
"message": "Login successful",
"token": "eyJhbGciOi..."
}The refresh token is set as an HTTP-only cookie automatically.
Request Body:
{
"email": "[email protected]"
}Success Response (200):
{
"success": true,
"message": "If this email exists, an OTP has been sent."
}Request Body:
{
"email": "[email protected]",
"otp": "482910"
}Success Response (200):
{
"success": true,
"message": "OTP verified successfully. You can now reset your password.",
"data": {
"resetToken": "eyJhbGciOi..."
}
}Headers:
Authorization: Bearer <resetToken>Request Body:
{
"newPassword": "newSecurePassword456"
}Success Response (200):
{
"success": true,
"message": "Password reset successfully. Please log in with your new password."
}📂 Project Structure
The generated boilerplate follows a clean, maintainable architecture:
JavaScript
├── .env.example
├── .gitignore
├── index.js # Entry point
├── package.json
└── src/
├── app.js # Express app configuration & middleware
├── config/ # Database connection
├── controllers/ # Route handlers (user.controller.js)
├── middlewares/ # Auth guard & rate limiters
├── models/ # Mongoose schemas (User, OTP, ResetToken)
├── routes/ # Express route definitions
├── services/ # Email service (Nodemailer + Gmail OAuth2)
├── utils/ # Token generation, OTP utilities
└── validations/ # Zod request validation schemasTypeScript
├── .env.example
├── .gitignore
├── tsconfig.json
├── package.json
└── src/
├── index.ts # Entry point
├── app.ts # Express app configuration & middleware
├── config/ # Database connection
├── controllers/ # Route handlers (user.controller.ts)
├── middlewares/ # Auth guard & rate limiters
├── models/ # Mongoose schemas (User, OTP, ResetToken)
├── routes/ # Express route definitions
├── services/ # Email service (Nodemailer + Gmail OAuth2)
├── types/ # Custom TypeScript type definitions
├── utils/ # Token generation, OTP utilities
└── validations/ # Zod request validation schemas🔒 Security Highlights
Password hashing — All passwords are hashed with bcrypt (10 salt rounds) before storage.
HTTP-only cookies — Refresh tokens are stored in
Secure,HttpOnly,SameSite: Strictcookies to prevent XSS attacks.Token rotation — On every refresh, both access and refresh tokens are rotated and the old refresh token is invalidated.
OTP brute-force protection — OTP attempts are tracked per record (max 5 attempts), and the OTP is deleted after exceeding the limit.
Comprehensive rate limiting — Every endpoint (except logout) is rate-limited using a dual-strategy approach:
| Endpoint | Strategy | Limit | Window | | --- | --- | --- | --- | |
/register| IP-only | 5 requests | 1 hour | |/login| IP-only + Email+IP | 20 req (IP) / 5 req (email) | 15 min / 1 hour | |/refresh-token| IP-only | 20 requests | 15 min | |/forget-password| Email+IP | 5 requests | 15 min | |/verify-reset-otp| Email+IP | 10 requests | 15 min | |/reset-password| Email+IP | 10 requests | 15 min |IP-only limiters key on client IP. Email+IP limiters use a compound
email:ipkey to prevent targeted abuse while allowing different users from the same IP.Single-use reset tokens — Password reset tokens include a unique
jticlaim and are marked as used after a single successful reset.Timing-safe responses — The forgot-password endpoint always returns the same response regardless of whether the email exists.
🛠️ Built With
| Dependency | Purpose | | --- | --- | | Express 5 | Web framework | | Mongoose | MongoDB ODM | | jsonwebtoken | JWT signing & verification | | bcrypt | Password hashing | | Zod | Schema validation | | Nodemailer | Email delivery | | express-rate-limit | Rate limiting | | cookie-parser | Cookie parsing | | cors | Cross-origin resource sharing | | dotenv | Environment variable loading |
TypeScript projects additionally include tsx for development and typescript for compilation.
📜 Scripts
JavaScript
| Script | Command | Description |
| --- | --- | --- |
| dev | node --watch index.js | Start dev server with auto-restart |
| start | node index.js | Start production server |
TypeScript
| Script | Command | Description |
| --- | --- | --- |
| dev | tsx watch src/index.ts | Start dev server with auto-restart |
| build | tsc | Compile TypeScript to JavaScript |
| start | node dist/index.js | Start compiled production server |
🤝 Contributing
Contributions, issues, and feature requests are welcome! Feel free to open an issue or submit a pull request.
📄 License
This project is licensed under the MIT License — see the LICENSE file for details.
👤 Author
Taksh Patel
