Production-ready Node.js backend framework with multi-database support
npm install @nexved/backend-framework
bash
npx @nexved/backend-framework
`
This will launch an interactive CLI to scaffold your project:
- Choose project name
- Select language (TypeScript/JavaScript)
- Pick databases (multi-select)
- Configure authentication
- Set up caching
- Choose ORM (Prisma/Drizzle/None)
$3
`bash
Clone the template
git clone https://github.com/NexVed/Backend-framework.git my-app
cd my-app/templates/express/typescript
Install dependencies
npm install
Copy environment file
cp .env.example .env
Start development
npm run dev
`
š Project Structure
`
my-app/
āāā app/
ā āāā api/ # File-based routes
ā āāā health/
ā ā āāā route.ts # GET /api/health
ā āāā users/
ā āāā route.ts # GET/POST /api/users
ā āāā [id]/
ā āāā route.ts # GET/PUT/DELETE /api/users/:id
āāā auth/ # Authentication module
āāā cache/ # Caching (memory/redis)
āāā core/ # Server & config
āāā database/ # Database adapters
ā āāā adapters/ # Provider implementations
āāā middleware/ # Express middleware
āāā orm/ # Prisma/Drizzle integration
āāā utils/ # Response helpers, logger
āāā backend.config.ts # Framework configuration
āāā server.ts # Entry point
āāā package.json
`
š File-Based Routing
Create routes by adding files in app/api/:
`typescript
// app/api/users/route.ts
export const GET = (req, res) => {
res.json({ users: [] });
};
export const POST = async (req, res) => {
const { name, email } = req.body;
// Create user...
res.status(201).json({ id: '1', name, email });
};
`
Dynamic routes use brackets:
`typescript
// app/api/users/[id]/route.ts
export const GET = (req, res) => {
const { id } = req.params;
res.json({ id, name: 'User' });
};
export const DELETE = (req, res) => {
const { id } = req.params;
// Delete user...
res.status(204).send();
};
`
āļø Configuration
Edit backend.config.ts to configure your app:
`typescript
import { defineConfig } from './core/config';
export default defineConfig({
server: {
port: 3000,
cors: { origin: '*', credentials: true },
},
database: {
default: 'supabase',
providers: {
supabase: {
url: process.env.SUPABASE_URL!,
anonKey: process.env.SUPABASE_ANON_KEY!,
},
mongodb: {
uri: process.env.MONGODB_URI!,
dbName: 'myapp',
},
},
},
auth: {
enabled: true,
jwt: {
secret: process.env.JWT_SECRET!,
expiresIn: '7d',
},
},
cache: {
enabled: true,
driver: 'memory', // or 'redis'
ttl: 3600,
},
});
`
š Database Usage
$3
`typescript
import { db } from './database';
// Use default database
const data = await db.default().from('users').select();
// Use specific provider
const supabase = db.supabase();
const { data: users } = await supabase.from('users').select('*');
// MongoDB
const mongodb = db.mongodb();
const users = await mongodb.collection('users').find({});
// PostgreSQL
const pg = db.postgresql();
const result = await pg.query('SELECT * FROM users WHERE id = $1', [userId]);
`
$3
`typescript
const health = await db.healthCheck();
// { supabase: true, mongodb: true, postgresql: false }
`
š Authentication
$3
`typescript
import { requireAuth, requireRole } from './middleware/auth';
// Require authentication
app.get('/api/profile', requireAuth(), (req, res) => {
res.json({ user: req.user });
});
// Require specific role
app.delete('/api/admin', requireAuth(), requireRole('admin'), (req, res) => {
// Only admins can access
});
`
$3
`typescript
import { generateToken, generateTokenPair, hashPassword, comparePassword } from './auth';
// Hash password
const hash = await hashPassword('mypassword');
// Verify password
const isValid = await comparePassword('mypassword', hash);
// Generate JWT
const token = await generateToken({ id: user.id, email: user.email });
// Generate access + refresh tokens
const { accessToken, refreshToken, expiresIn } = await generateTokenPair({ id: user.id });
`
š¾ Caching
`typescript
import { cache, cacheKey, cachePatterns } from './cache';
// Simple cache
cache.set('user:1', userData, 3600); // TTL in seconds
const user = cache.get('user:1');
// Cache-aside pattern
const user = await cachePatterns.getOrSet(
cacheKey.entity('user', userId),
() => fetchUserFromDB(userId),
3600
);
// Invalidate on write
await cachePatterns.invalidateOnWrite(
cacheKey.entity('user', userId),
() => updateUser(userId, data)
);
`
š”ļø Middleware
$3
`typescript
import { withRateLimit, strictRateLimit } from './middleware/rateLimit';
// Custom rate limit
app.use('/api', withRateLimit({ windowMs: 60000, max: 100 }));
// Strict limit for auth endpoints
app.post('/api/login', strictRateLimit(), loginHandler);
`
$3
`typescript
import { validateBody, validateQuery, schemas } from './middleware/validation';
import { z } from 'zod';
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
app.post('/api/users',
validateBody(createUserSchema),
(req, res) => {
// req.body is validated and typed
}
);
// With pagination
app.get('/api/users',
validateQuery(schemas.pagination),
(req, res) => {
const { page, limit } = req.query;
}
);
`
š Response Helpers
`typescript
import { success, created, paginated, notFound, badRequest } from './utils/response';
// Success response
success(res, { user });
// { success: true, data: { user } }
// Created (201)
created(res, { id: '1', name: 'New User' });
// Paginated
paginated(res, users, { page: 1, limit: 10, total: 100, totalPages: 10 });
// { success: true, data: [...], meta: { page, limit, total, totalPages } }
// Errors
badRequest(res, 'Invalid input', { field: 'email' });
notFound(res, 'User');
// { success: false, error: 'Not Found', message: 'User not found' }
`
š Logging
`typescript
import { logger, createLogger } from './utils/logger';
logger.info('Server started', { port: 3000 });
logger.error('Database error', error, { userId: '123' });
// Child logger with context
const userLogger = logger.child({ userId: '123' });
userLogger.info('User action'); // Automatically includes userId
`
šļø ORM Integration
$3
`typescript
import { prisma, connectPrisma, withTransaction } from './orm/prisma';
// Use Prisma client
const users = await prisma.user.findMany();
// With transaction
const result = await withTransaction(async (tx) => {
const user = await tx.user.create({ data: { name: 'John' } });
await tx.profile.create({ data: { userId: user.id } });
return user;
});
`
$3
`typescript
import { initDrizzle, getDrizzle, eq, desc } from './orm/drizzle';
import { users } from './db/schema';
// Initialize with Neon
await initDrizzle('neon', process.env.DATABASE_URL!);
const db = getDrizzle();
const allUsers = await db.select().from(users).where(eq(users.active, true));
`
š Environment Variables
`bash
Server
PORT=3000
NODE_ENV=development
Authentication
JWT_SECRET=your-secret-key
Databases (configure as needed)
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=xxx
MONGODB_URI=mongodb://localhost:27017
DATABASE_URL=postgresql://user:pass@localhost:5432/db
Cache
REDIS_URL=redis://localhost:6379
Logging
LOG_LEVEL=info
``