NovaxJS is a lightweight, high-performance web framework for Node.js designed for building modern web applications and APIs. With its minimalist design and powerful features, NovaxJS provides developers with an elegant solution for server-side development.
- Blazing Fast - Optimized for performance
- Intuitive Routing - Simple yet powerful route definitions
- Built-in Template Engine - Novax templating with conditionals and loops
- Enhanced File Handling - Robust file uploads and downloads
- Middleware Support - Flexible middleware architecture
- Static File Serving - With automatic MIME type detection
- CORS Support - Configurable CORS policies
- Plugin System - Extend framework functionality easily
- Modern Error Handling - Custom error pages and middleware
- Comprehensive Request Handling - Supports JSON, form-data, and urlencoded bodies
- Response Helpers - Built-in methods for common response patterns
- View Engine - Powerful template rendering
npm install novaxjs2
const Nova = require('novaxjs2');
const app = new Nova();
// Basic route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start server
app.at(3000, () => {
console.log('Server running on http://localhost:3000');
});
-
Advanced File Handling System
- Completely rewritten file upload processor with better memory management
- Configurable upload directory and file naming strategies
- Detailed file validation with size and type restrictions
- Automatic cleanup of temporary files
-
Enhanced Security Features
- Improved MIME type validation
- Strict file size limits enforcement
- Configurable maximum number of files per upload
- Option to preserve or randomize uploaded filenames
-
New FileHandler Class
- Dedicated class for all file operations
- Support for streaming large files
- Comprehensive file validation methods
- Built-in file cleanup utilities
-
Performance Optimizations
- Reduced memory footprint for file uploads
- Faster multipart form data parsing
- Improved error handling for malformed requests
-
Extended Configuration Options
- Unified file configuration system
- Simplified API for setting upload limits
- Better defaults for production environments
const Nova = require('novaxjs2');
const app = new Nova();
// Set port and optional host
app.at(3000, '0.0.0.0', () => {
console.log('Server started');
});
// Or just port with callback
app.at(3000, () => {
console.log('Server started');
});
app.get('/', (req, res) => {
res.send('Home Page');
});
app.post('/users', (req, res) => {
// Handle POST request
res.json({ success: true });
});
app.get('/users/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (req, res) => {
res.json({
postId: req.params.postId,
commentId: req.params.commentId
});
});
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
};
const auth = (req, res, next) => {
if (req.headers.authorization) {
next();
} else {
res.status(401).send('Unauthorized');
}
};
app.get('/secure', logger, auth, (req, res) => {
res.send('Secure Content');
});
app.get('/request-info', (req, res) => {
res.json({
method: req.method,
url: req.url,
query: req.query, // Query parameters
ip: req.ip, // Client IP address
protocol: req.protocol, // http or https
fullUrl: req.fullUrl, // Complete URL
headers: req.headers // Request headers
});
});
// JSON body
app.post('/api/users', (req, res) => {
console.log(req.body); // Parsed JSON
res.json({ received: true });
});
// Form data
app.post('/contact', (req, res) => {
console.log(req.body); // Parsed form data
res.send('Form submitted');
});
// File uploads
app.post('/upload', (req, res) => {
console.log(req.files); // Uploaded files
console.log(req.body); // Other form fields
res.json({ success: true });
});
// Send text/HTML
app.get('/text', (req, res) => {
res.send('Hello World');
});
// Send JSON
app.get('/json', (req, res) => {
res.json({ message: 'Hello World' });
});
// Set status code
app.get('/status', (req, res) => {
res.status(201).send('Created');
});
// Redirect
app.get('/old', (req, res) => {
res.redirect('/new');
});
// Set headers
app.get('/headers', (req, res) => {
res.set({
'X-Custom-Header': 'value',
'Cache-Control': 'no-cache'
}).send('Headers set');
});
// Send file
app.get('/download', (req, res) => {
app.sendFile('./files/document.pdf', 'application/pdf', res);
});
// Alternative file send
app.get('/page', (req, res) => {
app.sendFile('./views/page.html', res); // Defaults to text/html
});
// Runs for all requests
app.useMiddleware((req, res, next) => {
console.log('Request received');
next();
});
app.useErrorMiddleware((err, req, res, next) => {
console.error(err);
res.status(500).send('Something broke!');
});
// Serve files from /public directory
app.serveStatic('public');
// Custom static directory
app.serveStatic('assets');
// Files will be available at:
// /public/images/logo.png -> /images/logo.png
// Configure file upload settings
app.setFileConfig({
maxSize: 100, // 100MB max file size
allowedTypes: [ // Allowed MIME types
'image/jpeg',
'image/png',
'application/pdf'
],
maxFiles: 10, // Maximum files per upload
keepOriginalName: false // Randomize filenames for security
});
// Handle file upload
app.post('/upload', (req, res) => {
// File info structure:
const fileInfo = req.files.myfile;
/*
{
name: 'original.jpg', // Original filename
newname: 'file-123456789.jpg', // Saved filename
type: 'image/jpeg', // MIME type
size: 102400, // Size in bytes
path: '/tmp/uploads/file-123456789.jpg', // Full path
ext: '.jpg', // File extension
mimetype: 'image/jpeg' // MIME type (duplicate)
}
*/
// Process the file...
res.json({
success: true,
file: {
originalName: fileInfo.name,
savedName: fileInfo.newname,
size: fileInfo.size,
url: `/uploads/${fileInfo.newname}`
}
});
});
// Clean up uploads (can be called periodically)
app.fileHandler.clearUploads();
// Get a file stream for processing
app.get('/process-file/:filename', (req, res) => {
const filePath = path.join(app.fileHandler.uploadDir, req.params.filename);
try {
const fileStream = app.fileHandler.getFileStream(filePath);
fileStream.pipe(res);
} catch (err) {
res.status(404).send('File not found');
}
});
// Remove a file
app.delete('/files/:filename', (req, res) => {
const filePath = path.join(app.fileHandler.uploadDir, req.params.filename);
const success = app.fileHandler.removeFile(filePath);
res.json({ success });
});
<!-- views/home.html -->
<h1>Welcome, {{user.name}}!</h1>
{{#if user.isAdmin}}
<p>You have admin privileges</p>
{{else}}
<p>Standard user</p>
{{/if}}
<ul>
{{#each items}}
<li>{{this.name}} - ${{this.price}}</li>
{{/each}}
</ul>
// Configure view engine
app.setViewEngine('novax', {
viewsPath: './views' // default
});
// Render template
app.get('/', (req, res) => {
app.render('home', {
user: { name: 'John', isAdmin: true },
items: [
{ name: 'Product 1', price: 19.99 },
{ name: 'Product 2', price: 29.99 }
]
}).then(html => res.send(html));
});
// 404 Not Found
app.on(404, () => `
<h1>Page Not Found</h1>
<p>The requested page could not be found</p>
`);
app.error((err, req, res) => {
return `
<h1>Error ${err.statusCode || 500}</h1>
<p>${err.message}</p>
${process.env.NODE_ENV === 'development' ? `<pre>${err.stack}</pre>` : ''}
`;
});
function databasePlugin(context) {
// Add a method to the app
context.addMethod('connectToDatabase', function(config) {
this.dbConfig = config;
// Implementation here
});
// Add middleware
context.addMiddleware((req, res, next) => {
req.db = getDatabaseConnection();
next();
});
// Add configuration
context.setConfig('database', { defaultLimit: 100 });
}
// Use plugin
app.usePlugin(databasePlugin);
// Now we can use plugin methods
app.connectToDatabase({
host: 'localhost',
user: 'root',
password: 'secret'
});
// And middleware is automatically added
app.cors({
origins: ['http://localhost:3000', 'https://example.com'],
methods: 'GET, POST, PUT, DELETE, OPTIONS',
headers: 'Content-Type, Authorization, X-Custom-Header',
credentials: true
});
app.setViewEngine('novax', {
viewsPath: './templates' // Custom views directory
});
// Complete file configuration
app.setFileConfig({
maxSize: 100, // Max file size in MB
allowedTypes: [ // Allowed MIME types
'image/jpeg',
'image/png',
'application/pdf'
],
maxFiles: 5, // Max files per upload
keepOriginalName: false, // Randomize filenames
uploadDir: './custom-uploads' // Custom upload directory
});
// Or configure individually:
app.setFileSizeLimit(100); // 100MB
app.setAllowedFileTypes(['image/jpeg', 'image/png']);
app.setMaxFiles(10);
app.setKeepOriginalName(true);
NovaxJS follows these core principles:
- Minimalist Core - Only essential features in the core
- Extensible - Plugins for additional functionality
- Unopinionated - Flexible structure for different use cases
- Performance Focused - Optimized for speed and low memory usage
- Security Conscious - Safe defaults and validation for all operations
ISC License