Overview
The Resend OTP module adds secure email-based one-time password (OTP) verification to your Node.js Express application using the Resend API. The module automatically:- Installs all required dependencies
- Generates controllers, routes, and middleware
- Patches your main app file intelligently
- Injects environment variables to
.env - Supports both JavaScript and TypeScript
- Includes rate limiting for security
OTPs are stored in-memory with a 5-minute expiration. For production, consider implementing a persistent storage solution like Redis.
Installation
Run the following command in your project directory:Interactive Setup
The CLI will guide you through an interactive setup process with the following prompts:Specify Entry File
Enter your project’s main entry file (relative to root)
For TypeScript projects, if the file doesn’t exist, Devark will auto-detect
.ts files in your src/ directory.Resend API Key
Dependencies Installed
The module automatically installs the following packages:Runtime Dependencies
TypeScript Dev Dependencies (TypeScript only)
Generated File Structure
- JavaScript
- TypeScript
Configuration
The following environment variables are automatically added to your.env file:
Your Resend API key from the Resend Dashboard
The email address to send OTPs from. Must be a verified domain in Resend for production use.
Example .env
Generated Code
OTP Logic
- JavaScript
- TypeScript
The module generates
controllers/otp.js:Request Handlers
- JavaScript
- TypeScript
The module generates
controllers/otpFunctions.js:API Routes
- JavaScript
- TypeScript
The module generates
routes/otpRoutes.js:Rate Limiting Middleware
- JavaScript
- TypeScript
The module generates
middleware/rateLimit.js:API Endpoints
Send OTP
Sends a 6-digit OTP to the specified email address.Verify OTP
Verifies the OTP provided by the user.Usage Example
Frontend Integration
Complete Flow Example
Security Features
Rate Limiting
Limits each IP to 10 requests per 15 minutes to prevent abuse
OTP Expiration
OTPs automatically expire after 5 minutes
Secure Generation
Uses Node.js crypto module for cryptographically secure random numbers
Automatic Cleanup
Expired OTPs are automatically removed from storage
Customization
Change OTP Expiration Time
Editcontrollers/otp.js (or otp.ts):
Customize Email Template
Edit thehtmlContent in the sendOtp function:
Adjust Rate Limiting
Editmiddleware/rateLimit.js:
Change OTP Length
Editcontrollers/otp.js:
Troubleshooting
OTP emails not being delivered
OTP emails not being delivered
Solution:
- Verify your Resend API key is correct in
.env - Check that your
FROM_EMAILdomain is verified in Resend - For testing, use
onboarding@resend.dev - Check Resend dashboard for delivery logs
Rate limit errors (429)
Rate limit errors (429)
Solution: The rate limiter restricts each IP to 10 requests per 15 minutes. Either:
- Wait for the rate limit window to reset
- Adjust the limits in
middleware/rateLimit.js - Use different IPs for testing
OTP always shows as incorrect
OTP always shows as incorrect
Solution:
- Ensure you’re using the exact email address for both send and verify
- Check that the OTP hasn’t expired (5-minute default)
- Verify the OTP code matches exactly (6 digits)
- Check server logs for any errors during verification
TypeScript errors after installation
TypeScript errors after installation
Solution: The module installs TypeScript types automatically. If you still see errors:
Production storage concerns
Production storage concerns
Solution: The default in-memory storage isn’t suitable for production with multiple server instances. Consider:
- Implementing Redis for distributed OTP storage
- Using a database with TTL indexes (MongoDB, PostgreSQL)
- Implementing a hash-based approach without server storage
Getting a Resend API Key
Sign Up for Resend
Visit resend.com and create a free account.
Navigate to API Keys
Go to the API Keys page in your dashboard.
Production Considerations
Use Persistent Storage
Use Persistent Storage
Replace the in-memory
Map with Redis or a database to support multiple server instances.Implement Account Lockout
Implement Account Lockout
Add logic to lock accounts after multiple failed OTP attempts.
Log OTP Activities
Log OTP Activities
Track OTP generation and verification for security auditing.
Use Verified Domain
Use Verified Domain
Replace
onboarding@resend.dev with your verified domain email.Add HTTPS in Production
Add HTTPS in Production
Ensure all API requests are made over HTTPS to prevent interception.
Next Steps
Google OAuth
Add Google authentication alongside OTP
GitHub OAuth
Add GitHub authentication to your project

