A lightweight, framework-free Node.js project demonstrating a clean MVC structure inspired by Laravel. Includes routing, controllers, middleware, MySQL integration, form handling, security and a simple view Engine. All built from scratch.
When most developers think of Node.js, they immediately think of Express.js. But what if you could build a clean MVC architecture routing, controllers, models, views, middleware, security without any framework ? That’s exactly what I built in my project. It’s a lightweight MVC boilerplate that teaches you how frameworks work under the hood.
Why This Project ?
- No Frameworks: Everything is plain Node.js. Learn how MVC logic works internally.
- MVC Structure: Inspired by Laravel’s clarity and organization.
- Secure by Default: Includes CSRF, XSS protection, sessions, CORS and Rate limiting.
- Full Feature Set: Routing, controllers, models, validation, API support, view Engine and file uploads.
If you’ve ever wanted to understand what happens behind Express, Laravel or Django, this project is the perfect deep dive.
Routing & Route Service Provider
This project has a custom routing system for web and API endpoints, complete with global middleware and /api prefixes. Routes are defined like Laravel:
// routes/web.js
const Route = require('../system/WebRoute');
const UserController = require('../app/controllers/web/UserController');
Route.get('/users', UserController.index);
Route.post('/users', UserController.store);
module.exports = Route;
// routes/api.js
const Route = require('../system/ApiRoute');
const UserController = require('../app/controllers/api/UserController');
const AuthController = require('../app/controllers/api/AuthController');
Route.post('/users', UserController.store);
Route.post('/login', AuthController.create);
module.exports = Route;
Features:
- Supports GET, POST, PUT, DELETE.
- Middleware can be attached per route.
Middleware
Middleware enhances modularity, running before controllers for tasks like logging, authentication, validation, and CSRF protection. Just like Laravel’s pipeline.
const AuthMiddleware = require('../app/middleware/AuthMiddleware');
// Example usage
Route.post('/users', UserController.store, [AuthMiddleware]);
Controllers
Controllers manage the business logic and prepare responses for web or API routes:
// app/controllers/api/UserController.js
const response = require('../../../helpers/response');
const User = require('../../models/User');
class UserController {
async index(req, res) {
const users = await User.all();
return response.json(res, {
success: true,
message: 'Success',
data: users,
});
}
}
module.exports = new UserController();
Models with Fillable Support
Models extend a base Model class and define fillable fields to prevent mass assignment vulnerabilities. Just like Laravel’s fillable fields, models prevent mass assignment vulnerabilities.
// app/models/User.js
const Model = require('../../system/Model');
class User extends Model {
constructor() {
super('users', ['name', 'email', 'password']);
}
}
module.exports = new User();
Only name, email and password can be mass-assigned.
Usage in a controller:
await User.create({
name: 'Alamin',
email: 'alamin@gmail.com',
password: hash('1234')
});
View Engine
A minimalist templating engine allows server-side rendering with simple HTML interpolation, similar to Blade or EJS.
View Template (views/home.html):
<html>
<head><title>{{ title }}</title></head>
<body>
{{ content }}
</body>
</html>
Render from Controller:
const html = await view('home', {
title: 'Hello Node.js',
content: 'Hello World!'
});
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html);
Security First
The project includes essential security protections by default:
- CSRF Tokens for safe form submissions in web routes.
- XSS Sanitization using sanitize-html
- CORS Middleware for safe cross-origin requests.
- Rate Limiting to prevent abuse.
- Request Loggin for debugging and monitoring.
Form Handling & File Uploads
Supports application/json, x-www-form-urlencoded and multipart/form-data (via formidable)
const Validation = require('../../../system/Validation');
const { passes, errors } = await Validation.validate(
{ name, email, password },
{
name: 'required|min:3',
email: 'required|email|unique:users,email',
password: 'required|min:3'
}
);
if (! passes) {
return response.validationError(res, errors);
}
Quick Start
git clone git@github.com:alamincse/mvc-app-nodejs.git
cd mvc-app-nodejs
npm install
Run the server:
nodemon server
node server # or
npm run pm2:start # or use pm2
And create database tables with:
nodemon database # Or `node database`
Configure your .env file for database credentials and ports.
Access the Application
Open your browser and navigate to http://localhost:3000
Why This Architecture Stands Out ?
- Pure JavaScript: No reliance on Express or other heavy frameworks.
- Understand MVC deeply: Learn core patterns and workflows.
- Security-first: Shields common attacks with default middleware.
- Feature-rich: Includes templating, validation, models, routing, APIs.
- Ideal for learning: Perfect for developers keen on diving into MVC fundamentals.
Why You Should Try It ?
- Understand frameworks deeply: You’ll never see Express or Laravel the same way again.
- Educational: Great for students and self-learners.
- Extensible: Your own middleware, validation or auth system.
- Lightweight: Perfect for small projects and experiments.
Final Thoughts
Building mvc-app-nodejs demonstrates that frameworks are essentially layers of abstraction. By building an MVC system from scratch, you gain insight into the inner workings of routing, controllers, models, views and middleware.
Read more on the GitHub repository: MVC-APP-Nodejs
Top comments (0)