Package Exports
- nextrush
- nextrush/package.json
Readme
NextRush ๐
A modern, fast, and testable HTTP server framework for Node.js with TypeScript-first design, clean architecture, and Express-like API. Zero dependencies, maximum performance.
๐ Features
- ๐ฏ Express-Compatible API - Familiar
app.get(),req,ressyntax - โก Zero Dependencies - Lightweight and fast
- ๐ท TypeScript First - Full type safety out of the box
- ๐งช Testable Architecture - Clean code with dependency injection
- ๐๏ธ Clean Architecture - Single responsibility, interface-based design
- ๐ก๏ธ Built-in Error Handling - Comprehensive error management
- ๐ Dual API Support - Choose between Express-style or Context-based APIs
๐ฆ Installation
npm install nextrush
# or
yarn add nextrush
# or
pnpm add nextrush๐ Quick Start (Express-Style API)
This is the recommended approach for most developers - familiar and easy to use:
import { createApp } from 'nextrush';
const app = createApp();
// Middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next();
});
// Routes
app.get('/', (req, res) => {
res.json({ message: 'Hello from NextRush!' });
});
app.get('/users/:id', (req, res) => {
const userId = req.param('id');
res.json({ userId, name: `User ${userId}` });
});
app.post('/users', (req, res) => {
const userData = req.body;
res.status(201).json({
message: 'User created',
user: { id: Date.now(), ...userData },
});
});
// Start server
app.listen(3000, () => {
console.log('๐ Server running on http://localhost:3000');
});๐ API Comparison
Express-Style API (Recommended for most users)
Pros:
- โ Familiar Express.js syntax
- โ Easy migration from Express
- โ Quick to learn and use
- โ Extensive middleware ecosystem patterns
Example:
app.get('/users/:id', (req, res) => {
res.json({ userId: req.param('id') });
});Context-Based API (For advanced users)
Pros:
- โ Better testability
- โ More explicit dependencies
- โ Better TypeScript integration
- โ Cleaner separation of concerns
Example:
app.get('/users/:id', async (context: RequestContext) => {
const { response, params } = context;
response.statusCode = 200;
response.setHeader('Content-Type', 'application/json');
response.end(JSON.stringify({ userId: params.id }));
});๐ฏ When to Use Which API?
Use Express-Style API when
- ๐ Migrating from Express.js
- ๏ฟฝ Working with a team familiar with Express
- โก Need to build quickly
- ๐ Want to leverage existing Express knowledge
Use Context-Based API when
- ๐งช Writing extensive tests
- ๐๏ธ Building large, complex applications
- ๐ท Want maximum TypeScript safety
- ๐ฏ Need precise control over request/response handling
๐ฆ Installation
npm install nextrushyarn add nextrushpnpm add nextrush๐ Quick Start
Hello World in 30 seconds
import { createApp, ResponseHandler } from 'nextrush';
const app = createApp();
const responseHandler = new ResponseHandler();
app.get('/', async (context) => {
responseHandler.json(context.response, {
message: 'Hello from NextRush!',
timestamp: new Date().toISOString(),
});
});
await app.listen(3000);
console.log('๐ Server running on http://localhost:3000');Real-World Example
import {
createApp,
createRouter,
ResponseHandler,
type RequestContext,
type MiddlewareHandler,
ValidationError,
NotFoundError,
} from 'nextrush';
const app = createApp();
const responseHandler = new ResponseHandler();
// Middleware
const loggingMiddleware: MiddlewareHandler = async (context, next) => {
const start = Date.now();
console.log(`โ ${context.request.method} ${context.request.pathname}`);
await next();
console.log(
`โ ${context.request.method} ${context.request.pathname} (${
Date.now() - start
}ms)`
);
};
// Routes
app.use(loggingMiddleware);
app.get('/users/:id', async (context) => {
const userId = context.params.id;
if (!userId || isNaN(Number(userId))) {
throw new ValidationError('User ID must be a valid number');
}
// Simulate database lookup
const user = {
id: userId,
name: `User ${userId}`,
email: `user${userId}@example.com`,
};
responseHandler.json(context.response, user);
});
app.post('/users', async (context) => {
const userData = context.body as { name: string; email: string };
if (!userData.name || !userData.email) {
throw new ValidationError('Name and email are required');
}
const newUser = {
id: Date.now(),
...userData,
createdAt: new Date().toISOString(),
};
responseHandler.json(context.response, newUser, 201);
});
// Error handling
app.use(async (context, next) => {
try {
await next();
} catch (error) {
if (error instanceof ValidationError) {
responseHandler.error(context.response, error.message, 400);
} else {
responseHandler.error(context.response, 'Internal Server Error', 500);
}
}
});
await app.listen(3000);๐๏ธ Core Concepts
Application
The main application instance that handles HTTP requests.
import { createApp, Application } from 'nextrush';
// Factory function (recommended)
const app = createApp();
// Direct instantiation with options
const app = new Application({
timeout: 30000,
maxRequestSize: 1024 * 1024, // 1MB
});Routing
Express-like routing with parameter support.
// Basic routes
app.get('/users', getUsersHandler);
app.post('/users', createUserHandler);
app.put('/users/:id', updateUserHandler);
app.delete('/users/:id', deleteUserHandler);
// Route parameters
app.get('/users/:id', async (context) => {
const userId = context.params.id;
// Handle user by ID
});
// Multiple parameters
app.get('/users/:userId/posts/:postId', async (context) => {
const { userId, postId } = context.params;
// Handle user's specific post
});
// Query parameters
app.get('/search', async (context) => {
const { q, limit, page } = context.query;
// Handle search with query parameters
});Middleware
Composable middleware functions with async/await support.
import { MiddlewareHandler } from 'nextrush';
// Authentication middleware
const authMiddleware: MiddlewareHandler = async (context, next) => {
const authHeader = context.request.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
return responseHandler.error(context.response, 'Unauthorized', 401);
}
// Verify token logic here
await next();
};
// CORS middleware
const corsMiddleware: MiddlewareHandler = async (context, next) => {
context.response.setHeader('Access-Control-Allow-Origin', '*');
context.response.setHeader(
'Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE'
);
await next();
};
// Apply middleware
app.use(authMiddleware);
app.use(corsMiddleware);
// Route-specific middleware
app.get('/protected', authMiddleware, protectedHandler);Response Handling
Built-in response helpers for common operations.
import { ResponseHandler } from 'nextrush';
const responseHandler = new ResponseHandler();
// JSON responses
responseHandler.json(context.response, { data: 'value' });
responseHandler.json(context.response, { data: 'value' }, 201);
// Text responses
responseHandler.text(context.response, 'Hello World');
responseHandler.html(context.response, '<h1>Hello</h1>');
// Redirects
responseHandler.redirect(context.response, '/new-url');
responseHandler.redirect(context.response, '/moved', 301);
// Error responses
responseHandler.error(context.response, 'Not Found', 404);
// Custom headers
responseHandler.setHeaders(context.response, {
'X-API-Version': '1.0',
'Cache-Control': 'no-cache',
});Router
Create modular routers for better organization.
import { createRouter } from 'nextrush';
// User router
const userRouter = createRouter();
userRouter.get('/', getAllUsers);
userRouter.get('/:id', getUserById);
userRouter.post('/', createUser);
userRouter.put('/:id', updateUser);
userRouter.delete('/:id', deleteUser);
// Admin router
const adminRouter = createRouter();
adminRouter.use(adminAuthMiddleware); // Apply to all admin routes
adminRouter.get('/dashboard', adminDashboard);
// Mount routers
app.mount('/api/users', userRouter);
app.mount('/admin', adminRouter);๐ง Advanced Features
Custom Error Handling
import { ErrorHandler, NextRushError } from 'nextrush';
const errorHandler = new ErrorHandler({
includeStack: process.env.NODE_ENV === 'development',
logErrors: true,
customErrorHandler: (error, context) => {
// Send to monitoring service
console.error('Application Error:', error);
},
});
const app = createApp({ errorHandler });
// Custom error types
class CustomError extends NextRushError {
constructor(message: string) {
super(message, 'CUSTOM_ERROR', 400);
}
}Request Body Parsing
import { BodyParser } from 'nextrush';
const bodyParser = new BodyParser({
maxSize: 10 * 1024 * 1024, // 10MB
allowedContentTypes: [
'application/json',
'application/x-www-form-urlencoded',
'text/plain',
],
timeout: 30000,
});
const app = createApp({
requestHandler: new RequestHandler(bodyParser),
});
// Handle JSON data
app.post('/api/data', async (context) => {
const jsonData = context.body; // Automatically parsed
responseHandler.json(context.response, { received: jsonData });
});Type Safety
Full TypeScript support with custom context types.
import { RequestContext } from 'nextrush';
// Extend context with custom properties
interface CustomContext extends RequestContext {
user?: {
id: string;
name: string;
role: string;
};
}
const authMiddleware: MiddlewareHandler = async (
context: CustomContext,
next
) => {
// Add user to context
context.user = await validateToken(context.request.headers.authorization);
await next();
};
const protectedRoute = async (context: CustomContext) => {
// Type-safe access to user
const userName = context.user?.name;
responseHandler.json(context.response, { user: userName });
};๐งช Testing
NextRush is designed for easy testing with dependency injection.
// test/app.test.ts
import { Application, RequestHandler, ErrorHandler } from 'nextrush';
describe('NextRush Application', () => {
let app: Application;
let mockRequestHandler: jest.Mocked<RequestHandler>;
beforeEach(() => {
mockRequestHandler = {
handle: jest.fn(),
} as any;
app = new Application({
requestHandler: mockRequestHandler,
});
});
it('should handle requests correctly', async () => {
// Test your application with mocked dependencies
expect(mockRequestHandler.handle).toHaveBeenCalled();
});
});๐ Performance
NextRush offers excellent performance characteristics:
- Fast startup - Minimal initialization overhead
- Low memory usage - Efficient request handling
- High throughput - Optimized for concurrent requests
- Zero dependencies - No external dependency overhead
๐ Security Features
Built-in security features to protect your applications:
- Request validation - Automatic input sanitization
- Path traversal protection - Prevents directory traversal attacks
- Request size limits - Configurable body size limits
- Timeout handling - Request timeout protection
๐ Migration from Express
NextRush provides a familiar API for Express users:
// Express
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({ message: 'Hello' });
});
app.listen(3000);
// NextRush
import { createApp, ResponseHandler } from 'nextrush';
const app = createApp();
const responseHandler = new ResponseHandler();
app.get('/', async (context) => {
responseHandler.json(context.response, { message: 'Hello' });
});
await app.listen(3000);๐ API Reference
Core Classes
Application- Main application classRouter- Router for organizing routesRequestHandler- Handles HTTP request parsingResponseHandler- Provides response utilitiesBodyParser- Parses request bodiesErrorHandler- Manages error responses
Factory Functions
createApp(options?)- Create application instancecreateRouter(options?)- Create router instance
Types
RequestContext- Request/response contextRouteHandler- Route handler function typeMiddlewareHandler- Middleware function typeHttpMethod- HTTP method typesApplicationOptions- Application configuration options
๐ Examples
Basic REST API
import { createApp, ResponseHandler, ValidationError } from 'nextrush';
const app = createApp();
const responseHandler = new ResponseHandler();
// In-memory store
let users = [{ id: 1, name: 'John Doe', email: 'john@example.com' }];
// GET /users - List all users
app.get('/users', async (context) => {
responseHandler.json(context.response, users);
});
// GET /users/:id - Get user by ID
app.get('/users/:id', async (context) => {
const userId = parseInt(context.params.id);
const user = users.find((u) => u.id === userId);
if (!user) {
return responseHandler.error(context.response, 'User not found', 404);
}
responseHandler.json(context.response, user);
});
// POST /users - Create new user
app.post('/users', async (context) => {
const { name, email } = context.body as any;
if (!name || !email) {
throw new ValidationError('Name and email are required');
}
const newUser = {
id: users.length + 1,
name,
email,
};
users.push(newUser);
responseHandler.json(context.response, newUser, 201);
});
// Error handling
app.use(async (context, next) => {
try {
await next();
} catch (error) {
if (error instanceof ValidationError) {
responseHandler.error(context.response, error.message, 400);
} else {
responseHandler.error(context.response, 'Internal Server Error', 500);
}
}
});
await app.listen(3000);
console.log('๐ REST API running on http://localhost:3000');Middleware Example
import { createApp, ResponseHandler, type MiddlewareHandler } from 'nextrush';
const app = createApp();
const responseHandler = new ResponseHandler();
// Request logging middleware
const logger: MiddlewareHandler = async (context, next) => {
const start = Date.now();
const { method, pathname } = context.request;
console.log(`โ ${method} ${pathname}`);
await next();
const duration = Date.now() - start;
console.log(
`โ ${method} ${pathname} ${context.response.statusCode} (${duration}ms)`
);
};
// Rate limiting middleware
const rateLimit: MiddlewareHandler = async (context, next) => {
// Simple rate limiting logic
const clientIP = context.request.connection.remoteAddress;
// Check rate limit for clientIP
// If exceeded, return 429 Too Many Requests
await next();
};
// Apply middleware globally
app.use(logger);
app.use(rateLimit);
app.get('/', async (context) => {
responseHandler.json(context.response, { message: 'Hello World!' });
});
await app.listen(3000);๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
๐ License
MIT License - see LICENSE file for details.
๐ Links
๐ Support
If you find NextRush helpful, please consider:
- โญ Starring the repository
- ๐ Reporting bugs
- ๐ก Suggesting features
- ๐ Improving documentation
- ๐ค Contributing code
Built with โค๏ธ by Tanzim Hossain
NextRush - Fast, Modern, TypeScript-First HTTP Server Framework