saas-backend-kit
v1.0.4
Published
Production-grade modular backend toolkit for building scalable SaaS applications
Downloads
506
Maintainers
Readme
Drop-in Node.js/Express starter with JWT auth, rate limiting, Redis caching, and multi-tenant support — built for SaaS products.
✨ Features
| Module | Description | Powered By | |--------|-------------|------------| | 🔐 Authentication | JWT auth, RBAC, Google OAuth | jsonwebtoken, Passport | | ⚡ Task Queue | Redis-based background jobs | BullMQ | | 🔔 Notifications | Email, SMS, Webhooks, Slack | Nodemailer, Twilio | | ☁️ File Upload | Images, videos, docs to S3 | AWS SDK v3 | | 📋 Logger | Structured JSON logging | Pino | | 🛡️ Rate Limiting | Configurable API rate limiting | express-rate-limit | | ⚙️ Config Manager | Env variable validation | Zod | | 📦 API Responses | Standardized response format | Built-in |
📦 Installation
npm install saas-backend-kit🚀 Quick Start
import express from 'express';
import { auth, rateLimit, logger, config } from 'saas-backend-kit';
config.load();
const app = express();
app.use(express.json());
app.use(auth.initialize({ jwtSecret: 'your-secret-key' }));
app.use(rateLimit({ window: '1m', limit: 100 }));
app.get('/dashboard', auth.requireUser(), (req, res) => {
res.success({ message: 'Welcome!', user: req.user });
});
app.listen(3000, () => logger.info('Server running'));🗄️ Database
This toolkit supports both PostgreSQL and MongoDB.
PostgreSQL
1. Set the Database URL
Add the following to your .env file:
DATABASE_URL=postgresql://user:password@localhost:5432/mydbReplace the values with your actual database credentials:
user- Your PostgreSQL usernamepassword- Your PostgreSQL passwordlocalhost- Database host (uselocalhostfor local, or your cloud provider's host)5432- PostgreSQL port (default is 5432)mydb- Your database name
2. Using Prisma (Recommended)
If you're using Prisma, create a prisma/schema.prisma file:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Then run migrations:
npx prisma migrate dev --name init3. Using pg (Native PostgreSQL Client)
import pg from 'pg';
const { Pool } = pg;
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);4. Connection Pooling
For production, ensure your database connection is properly configured:
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});MongoDB
First, install the MongoDB driver:
npm install mongodb1. Set the MongoDB URL
Add the following to your .env file:
MONGODB_URL=mongodb://user:password@localhost:27017/mydbReplace the values with your actual MongoDB credentials:
user- Your MongoDB usernamepassword- Your MongoDB passwordlocalhost- Database host27017- MongoDB port (default is 27017)mydb- Your database name
2. Using the Database Module
import { database, config } from 'saas-backend-kit';
config.load();
await database.connect({
url: config.get('MONGODB_URL') || 'mongodb://localhost:27017/mydb',
});
const usersCollection = database.collection('users');
const user = await usersCollection.findOne({ email: '[email protected]' });
await usersCollection.insertOne({ name: 'John', email: '[email protected]' });3. Using connectTo for Custom Database Name
await database.connectTo(
'mongodb://localhost:27017',
'mydb',
{ maxPoolSize: 10 }
);4. Connection Options
await database.connect({
url: process.env.MONGODB_URL!,
options: {
maxPoolSize: 20,
minPoolSize: 5,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
w: 'majority',
}
});5. CRUD Operations
const users = database.collection('users');
await users.insertOne({ name: 'John', email: '[email protected]' });
const user = await users.findOne({ email: '[email protected]' });
await users.updateOne(
{ email: '[email protected]' },
{ $set: { name: 'John Doe' } }
);
await users.deleteOne({ email: '[email protected]' });
const allUsers = await users.find().toArray();🔐 Authentication
app.use(auth.initialize({
jwtSecret: 'your-secret-key',
jwtExpiresIn: '7d'
}));
await auth().register({ email, password, name });
await auth().login({ email, password });
auth.requireUser();
auth.requireRole('admin');
auth.requirePermission('read');⚡ Task Queue
import { queue } from 'saas-backend-kit';
const emailQueue = queue.create('email');
await emailQueue.add('sendEmail', { to: '[email protected]' });
queue.process('email', async (job) => {
await notify.email({ to: job.data.to, subject: 'Hello' });
}, { concurrency: 5 });🔔 Notifications
import { notify } from 'saas-backend-kit';
await notify.email({ to: '[email protected]', subject: 'Welcome' });
await notify.sms({ to: '+1234567890', message: 'Your code is 123456' });
await notify.slack({ text: 'New user registered!' });☁️ File Upload (S3)
import { upload } from 'saas-backend-kit';
upload.initialize({
region: 'us-east-1',
accessKeyId: 'your-access-key',
secretAccessKey: 'your-secret-key',
bucket: 'your-bucket-name'
});
const result = await upload.file(fileBuffer, { key: 'documents/file.pdf' });
const image = await upload.image(fileBuffer, 'photo.jpg');
const video = await upload.video(fileBuffer, 'video.mp4');
const signedUrl = await upload.getSignedUrl('path/to/file');
await upload.delete('path/to/file');📋 Logger
import { logger } from 'saas-backend-kit';
logger.info('Server started', { port: 3000 });
logger.error('Failed', { error: err.message });
const child = logger.child({ module: 'auth' });
child.info('User logged in');🛡️ Rate Limiting
app.use(rateLimit({ window: '1m', limit: 100 }));
app.use(rateLimit({ window: '1m', limit: 10, keyGenerator: (req) => req.user?.id }));⚙️ Config
config.load();
const port = config.int('PORT');
const isProduction = config.isProduction();📦 API Responses
res.success({ user });
res.created(user, 'Created');
res.paginated(users, page, limit, total);
res.error('Error message');🔧 Environment Variables
NODE_ENV=development
PORT=3000
# JWT
JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
JWT_EXPIRES_IN=7d
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-in-production
JWT_REFRESH_EXPIRES_IN=30d
# Redis
REDIS_URL=redis://localhost:6379
# Database (PostgreSQL)
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# Database (MongoDB)
MONGODB_URL=mongodb://user:password@localhost:27017/mydb
# Google OAuth (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:3000/auth/google/callback
# Email (SMTP) (optional)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
[email protected]
# Twilio SMS (optional)
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_PHONE_NUMBER=
# Slack (optional)
SLACK_WEBHOOK_URL=
# Rate Limiting
RATE_LIMIT_WINDOW=1m
RATE_LIMIT_LIMIT=100
# Logger
LOG_LEVEL=info
🤝 Contributing
Contributions, issues, and feature requests are welcome! Feel free to open a PR or issue.
Built with ❤️ by Ashish Kumar Maurya
Senior Full-Stack Developer · Dubai, UAE
saas-backend-kit · MIT License · Node.js · Express · Fastify · TypeScript · BullMQ · AWS S3 · Pino · Zod
