tekzee
v1.0.0
Published
A Node.js backend scaffolding CLI — generate Express, Auth, CRUD, Email, File Upload, AI, Sockets and Payments boilerplate instantly.
Maintainers
Readme
⚡ tekzee
A Node.js backend scaffolding CLI — generate Express, Auth, CRUD, Email, File Upload, AI, WebSockets and Payments boilerplate instantly.
npx tekzee📖 Table of Contents
- What is this?
- Installation
- Usage
- Project Structure
- Generators
- Shared Utilities
- Generated File Conventions
- Environment Variables
- Frequently Asked Questions
💡 What is this?
TEKZEE CLI is an interactive command-line tool for Node.js/Express/MongoDB backends.
Instead of copy-pasting boilerplate from old projects, you run one command and the CLI writes clean, consistent, production-aware files directly into your project — configs, controllers, routes, services, middleware, and .env snippets all at once.
Every generator follows the same pattern:
- Select providers / features via checkbox prompts
- Choose which files to generate
- Pick an output directory
- Confirm — files are written instantly
⚡ Installation
Run without installing (recommended):
npx tekzeeOr install globally:
npm install -g tekzee
tekzeeRequires Node.js 18+ and uses
inquirer@8(CommonJS compatible). If you seeTypeError: inquirer.prompt is not a function, run:npm install inquirer@8
🖥️ Usage
Interactive menu
tekzeeLaunches a menu — pick any generator with arrow keys and Enter.
Direct command
Run a generator without the menu:
tekzee startup
tekzee auth
tekzee crud
tekzee email
tekzee upload
tekzee ai
tekzee socket
tekzee paymentPlugin mode
Add a feature to an existing project:
tekzee add auth
tekzee add socket
tekzee add payment
tekzee add ai
tekzee add crud
tekzee add email
tekzee add uploadHelp
tekzee --help📂 Project Structure
tekzee/
├── index.js ← CLI entry point
├── package.json
├── generators/
│ ├── generateStartup.js ← Express + MongoDB boilerplate
│ ├── generateAuth.js ← JWT auth (model, controller, middleware, routes)
│ ├── generateCrud.js ← Dynamic CRUD with interactive field builder
│ ├── generateEmail.js ← Email service (Nodemailer, Resend, SendGrid)
│ ├── generateUpload.js ← File uploads (Local, Cloudinary, AWS S3)
│ ├── generateAi.js ← AI chat integration (4 providers)
│ ├── generateSocket.js ← Real-time (Socket.io or native ws)
│ └── generatePayment.js ← Payment integration (Stripe, Razorpay, PayPal)
└── utils/
└── fileUtils.js ← Safe file writer with .env append logic🔧 Generators
🚀 Startup Generator
What it does: Scaffolds a fresh Express + MongoDB server with everything wired up and ready to run.
Files it can generate:
| File | Purpose |
| ------------------ | -------------------------------------------------- |
| server.js | Entry point — starts the HTTP server |
| src/app.js | Express app — middleware, routes, DB connection |
| src/config/db.js | Mongoose connection with error handling |
| .env | Port and MongoDB URI |
| package.json | Pre-filled with express, mongoose, dotenv, nodemon |
| .gitignore | Ignores node_modules/, .env, dist/ |
Quick start after generating:
npm install express mongoose dotenv
node server.js
# Or with hot reload:
npx nodemon server.js🔐 Auth Generator
What it does: Generates a complete JWT authentication system with bcrypt password hashing, cookie-based tokens, and role-based access control.
Files it generates:
| File | Purpose |
| ------------------------------------ | ---------------------------------------------- |
| src/models/user.model.js | Mongoose user schema with bcrypt pre-save hook |
| src/controllers/auth.controller.js | register, login, getMe, logout |
| src/middleware/auth.middleware.js | protect + restrictTo(...roles) middleware |
| src/routes/auth.routes.js | Public + protected route setup |
| .env | JWT_SECRET, JWT_EXPIRES_IN, MONGO_URI |
API routes generated:
POST /api/auth/register → create account (name, email, password)
POST /api/auth/login → login (email, password)
GET /api/auth/me → get current user [protected]
POST /api/auth/logout → clear token cookie [protected]Wire up in app.js:
const cookieParser = require("cookie-parser");
app.use(cookieParser());
const authRoutes = require("./routes/auth.routes");
app.use("/api/auth", authRoutes);Using protect in other routes:
const { protect, restrictTo } = require("../middleware/auth.middleware");
router.get("/dashboard", protect, getMe);
router.delete("/user/:id", protect, restrictTo("admin"), deleteUser);⚙️ CRUD Generator
What it does: Generates a full CRUD API for any resource with an interactive field builder — you define the Mongoose schema fields on the fly.
Files it generates:
| File | Purpose |
| -------------------------------------- | -------------------------------------------------- |
| src/models/{name}.model.js | Mongoose schema built from your field prompts |
| src/controllers/{name}.controller.js | getAll (paginated), getOne, create, update, delete |
| src/routes/{name}.routes.js | RESTful routes with optional auth comments |
Field types supported: String, Number, Boolean, Date, ObjectId
Field options per field:
- Type selection
- Required toggle
- Default value
ObjectIdauto-gets aref: "ReferenceModel"comment to fill in
Example session:
Resource name: Product
Field name: title → Type: String | Required: yes
Field name: price → Type: Number | Required: yes | Default: 0
Field name: inStock → Type: Boolean | Required: no | Default: true
Field name: (blank) → doneAPI routes generated:
GET /api/products → get all (supports ?page=1&limit=10&sort=-createdAt)
GET /api/products/:id → get one
POST /api/products → create
PATCH /api/products/:id → update (only allowed fields)
DELETE /api/products/:id → deleteWire up in app.js:
const productRouter = require("./src/routes/product.routes");
app.use("/api/products", productRouter);📧 Email Generator
What it does: Generates a full email service with responsive HTML templates, a service layer, controller, and routes.
Supported providers:
| Provider | Notes | | -------------- | ---------------------------------------------------- | | Nodemailer | Works with any SMTP — Gmail, Mailtrap, custom server | | Resend | Modern API-based email, great DX | | SendGrid | Enterprise-grade, high deliverability |
Email templates included:
| Template | Variables |
| ---------------------- | ----------------------------------------------------------- |
| Welcome | name, APP_NAME, LOGIN_URL |
| Password Reset | name, RESET_URL, EXPIRES_IN |
| Email Verification | name, VERIFY_URL, EXPIRES_IN |
| Generic / Custom | name, SUBJECT, HEADING, BODY, CTA_URL, CTA_TEXT |
All templates use a shared {{KEY}} placeholder system — no templating library needed.
Files it generates:
| File | Purpose |
| ------------------------------------------------ | --------------------------------------------------------------- |
| src/templates/email/*.html.js | Responsive HTML email templates (shared across providers) |
| src/config/{provider}.js | Provider client / transporter |
| src/services/{provider}.service.js | sendEmail, sendWelcomeEmail, sendPasswordResetEmail, etc. |
| src/controllers/{provider}.email.controller.js | HTTP handlers |
| src/routes/{provider}.email.routes.js | Protected routes |
API routes generated:
POST /api/email/send → raw email (to, subject, html)
POST /api/email/welcome → welcome email (to, name)
POST /api/email/password-reset → reset email (to, name, resetUrl)
POST /api/email/verify → verification email (to, name, verifyUrl)
POST /api/email/custom → generic email (to, subject, body)Using the service directly (recommended for auth flows):
const { sendPasswordResetEmail } = require("../services/nodemailer.service");
// Inside your auth controller:
await sendPasswordResetEmail({
to: user.email,
name: user.name,
resetUrl: `${process.env.APP_URL}/reset-password?token=${token}`,
expiresIn: "15 minutes",
});📁 File Upload Generator
What it does: Generates a complete file upload system with per-provider storage, file filtering, size limits, and delete support.
Supported providers:
| Provider | Storage | Notes |
| -------------- | ----------------- | ------------------------------------------------------ |
| Local Disk | Server filesystem | Path traversal protected on delete |
| Cloudinary | Cloudinary CDN | Auto-optimised via quality: auto, fetch_format: auto |
| AWS S3 | AWS S3 Bucket | Uses AWS SDK v3 (@aws-sdk/client-s3) |
Features:
| Feature | Description |
| --------------------- | --------------------------------------------- |
| Single file upload | POST /single — form-data field: "file" |
| Multiple files upload | POST /multiple — form-data field: "files" |
| Image-only validation | Restricts to JPEG, PNG, WEBP, GIF |
| File size limits | Configurable via MAX_FILE_SIZE_MB env var |
| Delete file | DELETE /:filename / /:publicId / /:key |
Files it generates:
| File | Purpose |
| ------------------------------------------------- | --------------------------------------- |
| src/config/{provider}.js | Multer + provider storage config |
| src/controllers/{provider}.upload.controller.js | Upload + delete handlers |
| src/routes/{provider}.upload.routes.js | Routes with inline Multer error handler |
API routes generated:
POST /api/upload/{provider}/single → upload one file
POST /api/upload/{provider}/multiple → upload multiple files
DELETE /api/upload/local/:filename → delete local file
DELETE /api/upload/cloudinary/:publicId → delete from Cloudinary
DELETE /api/upload/s3/:key → delete from S3Wire up local static serving in app.js:
app.use("/uploads", express.static("uploads"));⚠️ Every routes file includes a
handleMulterErrormiddleware that catchesLIMIT_FILE_SIZE,LIMIT_FILE_COUNT, andLIMIT_UNEXPECTED_FILEerrors and returns clean 400 JSON — they won't hit your global error handler as unformatted crashes.
🤖 AI Generator
What it does: Generates an AI chat integration with in-memory conversation history, optional streaming, and a shared error middleware.
Supported providers:
| Provider | Models available | | ---------------------- | ------------------------------------------------------------------------------- | | OpenAI | gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-3.5-turbo | | Anthropic (Claude) | claude-opus-4-5, claude-sonnet-4-5, claude-haiku-4-5 | | Google Gemini | gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash | | Groq | llama-3.3-70b-versatile, llama-3.1-8b-instant, mixtral-8x7b-32768, gemma2-9b-it |
Files it generates:
| File | Purpose |
| ------------------------------------------ | ----------------------------------------------------------- |
| src/config/{provider}.js | Provider client initialisation |
| src/controllers/{provider}.controller.js | normalChat, streamChat (optional), clearHistory, getHistory |
| src/routes/{provider}.routes.js | Protected chat routes |
| src/middleware/aiError.middleware.js | Handles 401/429/404/503 AI errors cleanly |
API routes generated:
POST /api/ai/chat → chat with history (body: { message })
POST /api/ai/stream → streaming chat (body: { message }) [if streaming enabled]
GET /api/ai/history → view chat history
DELETE /api/ai/history → clear chat historyWire up in app.js:
const openaiRouter = require("./src/routes/openai.routes");
app.use("/api/ai", openaiRouter);
// Mount AFTER all routes:
const { aiErrorHandler } = require("./src/middleware/aiError.middleware");
app.use(aiErrorHandler);💡 History note: Chat history is stored in-memory per user (keyed by
req.user._id). For production, swap theMapin the controller for Redis or a DB collection.
🔌 Socket Generator
What it does: Generates a real-time server with rooms, private messaging, online presence tracking, and broadcast support.
Technology options:
| Option | Best for | | ------------- | ---------------------------------------------------------- | | Socket.io | Most projects — auto-reconnect, rooms, fallback transports | | Native ws | Lightweight use cases, minimal overhead |
Integration modes:
| Mode | Description |
| -------------- | ------------------------------------------------------------------------------ |
| Standalone | Generates its own server.js entry point |
| Plugin | Exports a createSocketServer(app) function to plug into existing Express app |
Files it generates:
| File | Purpose |
| --------------------------------------------------------------- | ---------------------------------- |
| src/config/socket.io.js or src/config/ws.js | Server + CORS setup |
| src/socket/socket.io.handler.js or src/socket/ws.handler.js | All event handlers |
| server.js | Entry point (standalone mode only) |
Supported events (both technologies):
| Event (client → server) | Payload | Description |
| ----------------------- | ----------------------- | ----------------------------------------------------- |
| user:register | { userId } | Register user for online tracking + private messaging |
| room:join | { room } | Join a named room |
| room:leave | { room } | Leave a named room |
| room:message | { room, message } | Send message to everyone in a room |
| private:message | { toUserId, message } | Send direct message to a user |
| broadcast | { message } | Send to all connected clients |
| Event (server → client) | Description |
| --------------------------------- | ------------------------ |
| user:online / user:offline | Presence updates |
| room:joined / room:left | Room membership changes |
| room:message | Incoming room message |
| private:message | Incoming direct message |
| private:sent / private:failed | DM delivery confirmation |
| broadcast | Global message |
💡 Production note: The
onlineUsersMap is in-memory. For multi-server deployments, replace it with a Redis adapter (socket.io-redis).
💳 Payment Generator
What it does: Generates a complete payment integration with one-time payments, subscriptions, refunds, and webhooks.
Supported providers:
| Provider | One-time | Subscriptions | Refunds | Webhooks | | ------------ | ------------------------- | ------------------------- | ------- | ---------------- | | Stripe | Payment Intents | Stripe Subscriptions API | ✅ | ✅ HMAC verified | | Razorpay | Orders + verify signature | Razorpay Plans API | ✅ | ✅ HMAC verified | | PayPal | Orders + capture | Billing Subscriptions API | ✅ | ✅ Event-based |
Files it generates per provider:
| File | Purpose |
| ------------------------------------------ | -------------------- |
| src/config/{provider}.js | Provider client |
| src/controllers/{provider}.controller.js | All payment handlers |
| src/routes/{provider}.routes.js | Protected routes |
API routes generated:
Stripe:
POST /api/payment/stripe/payment-intent → create payment intent
POST /api/payment/stripe/subscription → create subscription
GET /api/payment/stripe/subscription/:id → get subscription
DELETE /api/payment/stripe/subscription/:id → cancel subscription
POST /api/payment/stripe/refund → refund payment
POST /api/payment/stripe/webhook → Stripe webhook [raw body]Razorpay:
POST /api/payment/razorpay/order → create order
POST /api/payment/razorpay/verify → verify payment signature
POST /api/payment/razorpay/subscription → create subscription
GET /api/payment/razorpay/subscription/:id → get subscription
DELETE /api/payment/razorpay/subscription/:id → cancel subscription
POST /api/payment/razorpay/refund → refund payment
POST /api/payment/razorpay/webhook → Razorpay webhookPayPal:
POST /api/payment/paypal/order → create order
POST /api/payment/paypal/order/:orderId/capture → capture payment
POST /api/payment/paypal/subscription → create subscription
DELETE /api/payment/paypal/subscription/:id → cancel subscription
POST /api/payment/paypal/refund → refund capture
POST /api/payment/paypal/webhook → PayPal webhook⚠️ Stripe webhook must be mounted before
express.json()— it needs the raw body:app.use( "/api/payment/stripe/webhook", express.raw({ type: "application/json" }), require("./routes/stripe.routes"), );
🔧 Shared Utilities
utils/fileUtils.js
All generators use this single utility to write files safely.
const { createFileWithDirs } = require("../utils/fileUtils");
const { status } = createFileWithDirs("path/to/file.js", content);
// status → "created" | "appended" | "skipped"Behaviour:
- Creates all parent directories automatically (
mkdirSync({ recursive: true })) - For
.envfiles: appends new keys instead of overwriting, so existing values are never lost - Normalises
\r\n→\nbefore comparing.envkeys (Windows safe) - Uses a proper regex check (
^KEY\s*=) to avoid false positive partial key matches - Returns
{ status }— the caller owns the logging - Wraps everything in
try/catchand throws a descriptive error on failure
📁 Generated File Conventions
All generators follow these conventions so files work together without manual glue:
| Convention | Detail |
| ---------------------- | --------------------------------------------------------------------------------- |
| Auth middleware | Always at src/middleware/auth.middleware.js, exports protect and restrictTo |
| Route mounting | All routes mounted under /api/{feature}/{provider} |
| Error propagation | All async handlers call next(error) — compatible with a global error handler |
| Upload field names | Always "file" (single) and "files" (multiple) as form-data field names |
| AI history | Stored in Map<userId, messages[]> — swap with Redis for production |
| .env append | Running multiple generators never overwrites existing .env keys |
| Status summary | Every generator prints Created / Appended / Skipped / Failed counts after writing |
🌍 Environment Variables
Complete reference of all .env keys used across generators:
# ─── Core ─────────────────────────────────────────────────────────────────────
PORT=3000
NODE_ENV=development
MONGO_URI=mongodb://localhost:27017/your_db_name
# ─── Auth ─────────────────────────────────────────────────────────────────────
JWT_SECRET=your_super_secret_jwt_key
JWT_EXPIRES_IN=7d
# ─── AI ───────────────────────────────────────────────────────────────────────
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=...
GROQ_API_KEY=gsk_...
# ─── Socket ───────────────────────────────────────────────────────────────────
CLIENT_URL=http://localhost:5173
# ─── Payment ──────────────────────────────────────────────────────────────────
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
RAZORPAY_KEY_ID=rzp_test_...
RAZORPAY_KEY_SECRET=...
RAZORPAY_WEBHOOK_SECRET=...
PAYPAL_CLIENT_ID=...
PAYPAL_CLIENT_SECRET=...
PAYPAL_WEBHOOK_ID=...
PAYPAL_RETURN_URL=http://localhost:3000/payment/success
PAYPAL_CANCEL_URL=http://localhost:3000/payment/cancel
# ─── Email ────────────────────────────────────────────────────────────────────
APP_NAME=MyApp
APP_URL=http://localhost:3000
[email protected]
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASS=your_smtp_password
RESEND_API_KEY=re_...
SENDGRID_API_KEY=SG....
# ─── File Upload ──────────────────────────────────────────────────────────────
UPLOAD_DIR=uploads
MAX_FILE_SIZE_MB=5
MAX_FILES=10
CLOUDINARY_CLOUD_NAME=...
CLOUDINARY_API_KEY=...
CLOUDINARY_API_SECRET=...
CLOUDINARY_FOLDER=uploads
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_S3_BUCKET=your_bucket_name❓ Frequently Asked Questions
Q: TypeError: inquirer.prompt is not a function
npm install inquirer@8Inquirer v9+ switched to ES Modules. v8 is CommonJS-compatible and works out of the box.
Q: Can I run multiple generators into the same project?
Yes — that's the intended workflow. Run Startup first, then Auth, then CRUD for each resource, then any integrations you need. The .env append logic means keys are never duplicated or overwritten.
Q: What is the difference between tekzee crud and tekzee add crud?
They run the same generator. The tekzee add <plugin> syntax is just a more expressive way to say "I'm adding this to an existing project" — useful when running tekzee feels ambiguous mid-project.
Q: Do I need all providers for a generator?
No — every generator lets you deselect providers and features. Unused code is never written. For example you can set up Stripe only without Razorpay or PayPal.
Q: The generated code uses next(error) but there's no global error handler — what do I add?
Add this at the bottom of app.js, after all routes:
// Global error handler
app.use((err, req, res, next) => {
const status = err.status || err.statusCode || 500;
res.status(status).json({
success: false,
message: err.message || "Internal Server Error",
...(process.env.NODE_ENV === "development" && { stack: err.stack }),
});
});Q: How do I protect a generated CRUD route with auth?
Open the generated routes file and uncomment the auth middleware line:
// Before:
// const { protect, restrictTo } = require("../middleware/auth.middleware");
// After:
const { protect, restrictTo } = require("../middleware/auth.middleware");
router.route("/").get(getAllProducts).post(protect, createProduct);
router
.route("/:id")
.patch(protect, updateProduct)
.delete(protect, restrictTo("admin"), deleteProduct);Q: How do I swap the in-memory AI chat history for Redis?
In src/controllers/{provider}.controller.js, replace the Map with Redis calls:
// Replace this:
const histories = new Map();
const getHistory = (userId) => { ... };
// With this (using ioredis):
const redis = require("ioredis");
const client = new redis(process.env.REDIS_URL);
const getHistory = async (userId) => {
const data = await client.get(`chat:${userId}`);
return data ? JSON.parse(data) : [];
};
const saveHistory = async (userId, history) => {
await client.setex(`chat:${userId}`, 3600, JSON.stringify(history)); // 1hr TTL
};Built with ❤️ by [tekzee team]
⚡ npx tekzee — skip the setup, start building.
