npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

create-express-authkit

v2.1.1

Published

CLI to scaffold a Node.js + Express + MongoDB backend with auth built in

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.

npm version license


✨ 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
  TypeScript

Example:

npx create-express-authkit my-backend

All 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 dev

TypeScript projects also support npm run build and npm start for 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 schemas

TypeScript

├── .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: Strict cookies 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:ip key to prevent targeted abuse while allowing different users from the same IP.

  • Single-use reset tokens — Password reset tokens include a unique jti claim 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