@threew/app
v1.0.6
Published
Modern, lightweight, modular, and scalable backend framework for Node.js, built with TypeScript and zero runtime dependencies.
Maintainers
Readme
@threew/app
Modern, lightweight, modular, and scalable backend framework for Node.js, built with TypeScript and zero runtime dependencies.
Features
- Modern Architecture: Modular design, ready to be split into sub-packages.
- TypeScript First: Full type safety and excellent developer experience.
- Dual Package Support: Native support for both ESM and CommonJS.
- High Performance: Lightweight core with minimal overhead.
- Built-in Essentials: Includes Router, Middleware Engine, Body Parser, Logger, and Rate Limiter.
Installation
npm install @threew/appQuick Start
ESM
import { createApp, logger } from '@threew/app';
const app = createApp();
app.use(logger());
app.get('/', (ctx) => {
ctx.res.success({ message: 'Hello from Threew!' });
});
app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});CommonJS
const { createApp, logger } = require('@threew/app');
const app = createApp();
app.use(logger());
app.get('/', (ctx) => {
ctx.res.success({ message: 'Hello from Threew!' });
});
app.listen(3000);Routing
Support for all standard HTTP methods:
app.get('/users', handler);
app.post('/users', handler);
app.put('/users/:id', handler);
app.patch('/users/:id', handler);
app.delete('/users/:id', handler);Route Parameters
Access route parameters via ctx.req.params:
app.get('/users/:id', (ctx) => {
const userId = ctx.req.params.id;
ctx.res.json({ userId });
});Query Parser
Access query parameters via ctx.req.query:
// GET /search?q=node&page=1
app.get('/search', (ctx) => {
const { q, page } = ctx.req.query;
ctx.res.json({ q, page });
});Middleware
Flexible middleware system inspired by Koa/Express:
app.use(async (ctx, next) => {
console.log('Before');
await next();
console.log('After');
});Route Groups
Organize your routes with groups and shared middleware:
app.group('/api/v1', (router) => {
router.get('/users', getUsers);
router.post('/users', createUser);
}, authMiddleware);Body Parser
Built-in support for:
application/jsonapplication/x-www-form-urlencodedtext/plain
app.post('/data', (ctx) => {
console.log(ctx.req.body);
ctx.res.created(ctx.req.body);
});Rate Limiter
Prevent abuse with the built-in rate limiter:
import { rateLimit } from '@threew/app';
app.use(rateLimit({
windowMs: 60000, // 1 minute
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests'
}));Logger
Simple request logging middleware:
import { logger } from '@threew/app';
app.use(logger());API Reference
Response Wrapper Helpers
res.success(data): Sends 200 OK with{ success: true, data }res.created(data): Sends 201 Created with{ success: true, data }res.error(message, code): Sends error responseres.badRequest(message): Sends 400 Bad Requestres.unauthorized(message): Sends 401 Unauthorizedres.forbidden(message): Sends 403 Forbiddenres.notFound(message): Sends 404 Not Foundres.conflict(message): Sends 409 Conflictres.internalError(message): Sends 500 Internal Server Error
Static Files
Serve static files like HTML, CSS, JavaScript, images, and more:
Basic Usage (ESM)
import { createApp, staticFiles } from '@threew/app';
import path from 'path';
const app = createApp();
// Serve files from 'public' directory
app.use(staticFiles(path.join(process.cwd(), 'public')));
app.listen(3000);Basic Usage (CommonJS)
const { createApp, staticFiles } = require('@threew/app');
const path = require('path');
const app = createApp();
// Serve static files from 'public' folder
app.use(staticFiles(path.join(__dirname, 'public')));
app.listen(3000);With Options
app.use(staticFiles(path.join(process.cwd(), 'public'), {
index: 'index.html', // Default file for directories
maxAge: 86400000, // Cache duration in ms (1 day)
etag: true, // Enable ETag header
cacheControl: true, // Enable Cache-Control header
dotfiles: 'ignore', // How to handle dotfiles
lastModified: true, // Enable Last-Modified header
immutable: false, // Add immutable directive to cache
setHeaders: (res, filePath, stat) => {
// Custom headers per file
if (filePath.endsWith('.html')) {
res.setHeader('X-Custom', 'HTML file');
}
}
}));Multiple Directories
// Serve from multiple folders (order matters)
app.use(staticFiles(path.join(process.cwd(), 'public')));
app.use(staticFiles(path.join(process.cwd(), 'uploads')));
app.use(staticFiles(path.join(process.cwd(), 'assets')));Manual File Serving
import { sendFile } from '@threew/app';
// Serve specific file on route
app.get('/', sendFile(path.join(process.cwd(), 'public', 'index.html')));
app.get('/about', sendFile(path.join(process.cwd(), 'public', 'about.html')));Folder Structure Example
your-project/
├── public/
│ ├── index.html
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── app.js
│ └── images/
│ └── logo.png
├── src/
└── package.jsonSupported MIME Types
- HTML, CSS, JavaScript, JSON
- PNG, JPG, GIF, SVG, ICO, WebP
- WOFF, WOFF2, TTF, EOT
- PDF, ZIP, MP3, MP4
- And more...
License
MIT
