Complete API reference for the Node.js MVC Framework.
The Boot module is responsible for starting the application and managing its lifecycle.
Starts the application by initializing all core modules in sequence.
const Boot = require('@core/boot.core')
await Boot.start()Returns: Promise<void>
Throws: Error if application fails to start
Manages database connections and Sequelize models.
Initializes database connection and loads models.
const Database = require('@core/database.core')
await Database.init()Returns: Promise<void>
Retrieves a loaded Sequelize model by name.
const User = Database.getModel('User')
const users = await User.findAll()Parameters:
name(string): Model name
Returns: Sequelize Model instance
Gets the Sequelize instance.
const sequelize = Database.getInstance()
await sequelize.query('SELECT * FROM users')Returns: Sequelize instance
Closes the database connection.
await Database.close()Returns: Promise<void>
Note: Since v2.0.0,
Database.close()is only called during shutdown ifconfig.database.statusistrue.
Object containing all loaded models.
const models = Database.models
console.log(Object.keys(models)) // ['User', 'Post', ...]Manages Express application and middleware configuration.
Initializes Express app with middlewares and routes.
const Express = require('@core/express.core')
Express.init()Returns: void
Gets the Express application instance.
const app = Express.instance()
app.get('/custom', (req, res) => {
res.send('Custom route')
})Returns: Express application
The Express application instance.
const app = Express.appThe Express Router instance.
const router = Express.routerWinston-based logging system with file rotation.
Logs informational messages.
const Logger = require('@core/logger.core')
Logger.info('user', 'User logged in successfully')Parameters:
context(string): Log context/layermessage(string): Log message
Logs error messages.
Logger.error('database', 'Connection failed')Parameters:
context(string): Error contextmessage(string): Error message
Logs warning messages.
Logger.warn('auth', 'Invalid token attempt')Parameters:
context(string): Warning contextmessage(string): Warning message
Logs debug messages (only in development).
Logger.debug('query', 'SELECT * FROM users')Parameters:
context(string): Debug contextmessage(string): Debug message
Logs error objects with stack traces.
try {
// some code
} catch (err) {
Logger.set(err, 'controller')
}Parameters:
error(Error): Error objectcontext(string): Error context
JSON Web Token utilities for authentication.
Creates a JWT token.
const JWT = require('@core/jwt.core')
const token = JWT.sign({ userId: 123, role: 'admin' }, '7d')Parameters:
payload(Object): Token payload dataexpiresIn(string, optional): Expiration time (default from config)
Returns: string - JWT token
Verifies and decodes a JWT token.
const decoded = JWT.verify(token)
if (decoded) {
console.log(decoded.userId) // 123
}Parameters:
token(string): JWT token to verify
Returns: Object|null - Decoded payload or null if invalid
Decodes a JWT token without verification.
const decoded = JWT.decode(token)
console.log(decoded)Parameters:
token(string): JWT token
Returns: Object|null - Decoded payload or null
Email sending functionality with template support.
Initializes the mailer transport.
const Mailer = require('@core/mailer.core')
Mailer.init()Returns: void
Sends an email using an EJS template.
v2.0.0: Validates
to,subject,templatebefore processing. Throws descriptive errors instead of propagating nodemailer errors.
await Mailer.send('user@example.com', 'Welcome!', 'welcome', { username: 'John' })Parameters:
to(string): Recipient email — required, throws if emptysubject(string): Email subject — required, throws if emptytemplate(string): Template name (without.email.ejs) — required, throws if file not founddata(Object): Data to pass to template
Returns: Promise<Object> - Email info
Template Location: public/views/templates/email/{template}.email.ejs
Sends raw HTML email without requiring a template file.
await Mailer.sendRaw('user@example.com', 'Hello!', '<h1>Hello World</h1>')Parameters:
to(string): Recipient emailsubject(string): Email subjecthtml(string): Raw HTML content
Returns: Promise<Object> - Email info
Verifies mailer connection.
const isValid = await Mailer.verify()
console.log(isValid) // true or falseReturns: Promise<boolean> - Connection status
Lifecycle hooks system for running code at specific points.
Registers a hook callback.
const Hooks = require('@core/hooks.core')
Hooks.register('before', async () => {
console.log('Before app starts')
})Parameters:
lifecycle(string): Hook lifecycle ('before', 'after', 'shutdown')callback(Function): Async function to execute
Lifecycles:
before: Before application initializationafter: After application startsshutdown: During graceful shutdown
Executes all hooks for a specific lifecycle.
await Hooks.run('after')Parameters:
lifecycle(string): Hook lifecycle to run
Returns: Promise<void>
Socket.IO configuration and management.
Initializes Socket.IO with the HTTP server.
const Socket = require('@core/socket.core')
const server = require('http').createServer(app)
Socket.init(server)Parameters:
server(Object): HTTP/HTTPS server instance
Returns: void
Gets the Socket.IO instance.
const io = Socket.getInstance()
io.emit('broadcast', { message: 'Hello everyone' })Returns: Socket.IO Server instance
Gracefully closes the Socket.IO server. Should be called during application shutdown.
await Socket.close()Returns: Promise<void>
The Socket.IO server instance.
const io = Socket.ioHTTP/HTTPS server creation and management.
Creates an HTTP or HTTPS server.
v2.0.0 Fix: No longer passes invalid options to
http.createServer(). Options likepoweredByare not valid Node.js HTTP server options.
const Server = require('@core/server.core')
const server = Server.create(expressApp)Parameters:
app(Object): Express application instance
Returns: HTTP/HTTPS Server instance
Starts the server listening on specified port.
await Server.listen(server, 3025)
await Server.listen(server, 3025, '127.0.0.1') // Bind to specific hostParameters:
server(Object): Server instanceport(number): Port numberhost(string, optional): Host to bind (default:0.0.0.0)
Returns: Promise<void>
Applies server-level timeout settings from config.server.options.
const server = Server.create(app)
Server.applyOptions(server) // Sets keepAliveTimeout, requestTimeout, headersTimeoutReads from config:
config.server.options.keepAliveTimeoutconfig.server.options.requestTimeoutconfig.server.options.headersTimeout
Runtime environment configuration.
Configures runtime environment (timezone, NODE_ENV).
const Runtime = require('@core/runtime.core')
Runtime.init()Returns: void
Global error handling for Express.
Initializes global error handler middleware.
const ErrorHandler = require('@core/errorHandler.core')
ErrorHandler.init(app)Parameters:
app(Object): Express application instance
Returns: void
Base class for all controllers. Provides standardized JSON response methods.
Async error wrapper. Eliminates repetitive try/catch in controller methods.
const BaseController = require('@app/http/controllers/base.controller')
// Before: manual try/catch
static async getAll(req, res) {
try {
const result = await UserService.getAll()
return BaseController.json(res, result)
} catch (err) {
return BaseController.serverError(res, err.message)
}
}
// After: use handle()
static getAll = BaseController.handle(async (req, res) => {
const result = await UserService.getAll()
return BaseController.json(res, result)
})Errors are automatically forwarded to Express error handler via next(err).
Universal JSON response builder. Can accept a BaseService.json() output object directly.
const result = await UserService.getAll()
return BaseController.json(res, result) // Reads status/code/message/data from result200 success response.
201 created response.
Error response.
422 validation error response.
404 response.
401 response.
403 response.
500 response.
Paginated response with meta information.
return BaseController.paginated(res, users, {
total: 100,
page: 1,
limit: 10,
totalPages: 10
})204 no content response.
Base class for all services. Provides standardized response object builders.
Universal response builder. Returns an object compatible with BaseController.json().
return this.json(true, 200, 'Success', data)Shortcut for 200 success.
return this.success('Users retrieved', users)Shortcut for 201 created.
return this.created('User created', newUser)Generic error shortcut (default 400).
return this.fail('Bad request')
return this.fail('Payment required', 402)Shortcut for 404.
return this.notFound('User not found')Shortcut for 401.
return this.unauthorized('Invalid token')Shortcut for 403.
return this.forbidden('Access denied')Shortcut for 409 (duplicate data).
return this.conflict('Email already registered')Shortcut for 422 with errors array.
return this.validationFail('Validation error', [{ field: 'email', message: 'Invalid' }])Shortcut for 500.
return this.serverError('Database error')Using express-fileupload, files are available in req.files.
Routes.post('/upload', ({ req, res }) => {
// Check if files exist
if (!req.files || !req.files.file) {
return res.status(400).json({
success: false,
message: 'No file uploaded',
})
}
const file = req.files.file
// File properties
console.log(file.name) // Original filename
console.log(file.mimetype) // MIME type
console.log(file.size) // File size in bytes
console.log(file.tempFilePath) // Temp file path
// Move file to destination
const uploadPath = __dirname + '/uploads/' + file.name
file.mv(uploadPath, (err) => {
if (err) {
return res.status(500).json({
success: false,
message: 'File upload failed',
error: err,
})
}
res.json({
success: true,
message: 'File uploaded successfully',
filename: file.name,
})
})
})Routes.post('/upload-multiple', ({ req, res }) => {
if (!req.files || !req.files.files) {
return res.status(400).json({ error: 'No files uploaded' })
}
const files = Array.isArray(req.files.files) ? req.files.files : [req.files.files]
files.forEach((file) => {
const uploadPath = __dirname + '/uploads/' + file.name
file.mv(uploadPath)
})
res.json({ message: `${files.length} files uploaded` })
})Routes.post('/upload', ({ req, res }) => {
if (!req.files || !req.files.file) {
return res.status(400).json({ error: 'No file' })
}
const file = req.files.file
// Validate file size (5MB max)
if (file.size > 5 * 1024 * 1024) {
return res.status(400).json({ error: 'File too large' })
}
// Validate MIME type
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
return res.status(400).json({ error: 'Invalid file type' })
}
// Process file...
})Using @refkinscallv/express-routing package.
const Routes = require('@refkinscallv/express-routing')
// GET route
Routes.get('/users', ({ req, res }) => {
res.json({ users: [] })
})
// POST route
Routes.post('/users', ({ req, res }) => {
res.json({ message: 'User created' })
})
// PUT route
Routes.put('/users/:id', ({ req, res }) => {
res.json({ id: req.params.id })
})
// DELETE route
Routes.delete('/users/:id', ({ req, res }) => {
res.json({ deleted: true })
})
// PATCH route
Routes.patch('/users/:id', ({ req, res }) => {
res.json({ updated: true })
})Routes.get('/users/:id', ({ req, res }) => {
const userId = req.params.id
res.json({ userId })
})
Routes.get('/posts/:postId/comments/:commentId', ({ req, res }) => {
const { postId, commentId } = req.params
res.json({ postId, commentId })
})Routes.get('/search', ({ req, res }) => {
const { q, page, limit } = req.query
res.json({ query: q, page, limit })
})
// GET /search?q=nodejs&page=1&limit=10const authMiddleware = (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' })
}
next()
}
Routes.get('/protected', authMiddleware, ({ req, res }) => {
res.json({ message: 'Protected data' })
})// API routes with prefix
Routes.group({ prefix: '/api/v1' }, () => {
Routes.get('/users', userController.index)
Routes.post('/users', userController.store)
})
// Results in: /api/v1/usersAll configuration in app/config.js.
module.exports = {
app: {
/* app settings */
},
server: {
/* server settings */
},
express: {
cors: {
/* CORS options */
},
static: {
/* static files */
},
view: {
/* view engine */
},
fileupload: {
/* file upload options */
},
},
socket: {
/* Socket.IO options */
},
database: {
/* database settings */
},
jwt: {
/* JWT settings */
},
mailer: {
/* email settings */
},
}const config = require('@app/config')
console.log(config.app.port) // 3025
console.log(config.database.host) // localhost
console.log(config.jwt.expiresIn) // 7d- Error Handling: Always use try-catch blocks and log errors
- Validation: Validate user inputs before processing
- Security: Use JWT for authentication, validate file uploads
- Logging: Use appropriate log levels (info, warn, error, debug)
- Database: Use transactions for complex operations
- File Uploads: Validate file types and sizes
- Environment: Use different configs for development/production
// app/routes/auth.route.js
const Routes = require('@refkinscallv/express-routing')
const Database = require('@core/database.core')
const JWT = require('@core/jwt.core')
const Mailer = require('@core/mailer.core')
const bcrypt = require('bcrypt')
Routes.post('/register', async ({ req, res }) => {
try {
const { email, password, name } = req.body
// Validate input
if (!email || !password || !name) {
return res.status(400).json({
success: false,
message: 'All fields required',
})
}
// Get User model
const User = Database.getModel('User')
// Check if user exists
const existing = await User.findOne({ where: { email } })
if (existing) {
return res.status(400).json({
success: false,
message: 'Email already registered',
})
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10)
// Create user
const user = await User.create({
email,
password: hashedPassword,
name,
})
// Generate JWT
const token = JWT.sign({ userId: user.id })
// Send welcome email
await Mailer.send(email, 'Welcome!', 'welcome', { name })
res.json({
success: true,
token,
user: {
id: user.id,
name: user.name,
email: user.email,
},
})
} catch (err) {
Logger.set(err, 'auth')
res.status(500).json({
success: false,
message: 'Registration failed',
})
}
})Previously, config.server.options was passed directly to http.createServer(). These options (poweredBy, maxHeaderSize, etc.) are NOT valid Node.js HTTP server options. They are now discarded. Server-level timeouts (keepAliveTimeout, requestTimeout, headersTimeout) must be applied via Server.applyOptions(server) (called automatically by Boot).
// Before (v1.0.5): returned 400
// After (v2.0.0): returns 422 (correct HTTP status for validation errors)
BaseController.validationError(res, validation) // → 422 Unprocessable EntityThe Database.close() method is asynchronous and returns a Promise:
// Before (v1.0.0)
Database.close()
// After (v1.0.5+)
await Database.close()Framework Version: 2.0.0
Last Updated: 2026-03-11
For more examples and detailed guides, see the README.md.