🟢 Backend JavaScript
Node.js & Express Cheatsheet
Modules, file system, HTTP, Express routing, middleware and MongoDB — complete Node.js reference.
01
Node.js Basics
▼
What is Node.js
JavaScript runtime built on Chrome V8. Non-blocking I/O. Single-threaded event loop.
Why Node.js
Fast for I/O-heavy tasks (APIs, servers). Same language front+back. Huge npm ecosystem.
Event loop
Call stack -> Web APIs -> Callback queue -> Event loop -> Call stack.
REPL
Read-Eval-Print Loop. Type 'node' in terminal to enter.
Global objects
__dirname, __filename, process, require, module, exports, console, setTimeout, setInterval
JSNode.js version + run
node --version # check version node app.js # run file nodemon app.js # auto-restart on change (install: npm i -g nodemon)
02
Modules & npm
▼
JSModules
// CommonJS (Node.js default)
const fs = require('fs');
const path = require('path');
const myModule = require('./utils');
// Export
module.exports = { greet, add };
module.exports = function() {};
// ES Modules (add 'type':'module' in package.json)
import fs from 'fs';
export const greet = (name) => `Hello ${name}`;
export default class MyClass {}
JSnpm basics
npm init -y # create package.json npm install express # install package npm install nodemon --save-dev # dev dependency npm install -g pm2 # global install npm run start # run script npm update # update packages npm list # list installed packages npx create-react-app myapp # run without installing
03
File System
▼
JSFile system operations
const fs = require('fs');
const path = require('path');
// Async (preferred)
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Promise-based
const fsPromises = require('fs').promises;
const data = await fsPromises.readFile('file.txt', 'utf8');
await fsPromises.writeFile('out.txt', 'content');
// Sync (blocks - avoid in server)
const content = fs.readFileSync('file.txt', 'utf8');
// Path utilities
path.join(__dirname, 'files', 'data.json');
path.extname('file.txt'); // '.txt'
path.basename('/path/to/file.txt'); // 'file.txt'
💡
Always use async file operations in a server. Sync operations block the event loop and hurt performance.
04
HTTP & Events
▼
JSHTTP server + EventEmitter
const http = require('http');
// Raw HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Hello!' }));
});
server.listen(3000, () => console.log('Running on port 3000'));
// EventEmitter
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const emitter = new MyEmitter();
emitter.on('data', (payload) => console.log('Received:', payload));
emitter.emit('data', { id: 1, name: 'Ali' });
05
Express.js Setup
▼
JSExpress setup
npm install express cors helmet morgan dotenv
// server.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
require('dotenv').config();
const app = express();
// Middleware
app.use(express.json()); // parse JSON body
app.use(express.urlencoded({ extended: true })); // parse form data
app.use(cors()); // enable CORS
app.use(helmet()); // security headers
app.use(morgan('dev')); // request logging
// Routes
app.use('/api/users', require('./routes/users'));
app.use('/api/posts', require('./routes/posts'));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server on port ${PORT}`));
06
Routing
▼
JSExpress routing
const express = require('express');
const router = express.Router();
// Route params and query
router.get('/users/:id', (req, res) => {
const { id } = req.params; // /users/123
const { sort, limit } = req.query; // ?sort=name&limit=10
res.json({ id, sort, limit });
});
// Chained routes
router.route('/posts')
.get(getAllPosts)
.post(createPost);
router.route('/posts/:id')
.get(getPost)
.put(updatePost)
.delete(deletePost);
module.exports = router;
💡
Separate route files by resource: users.js, posts.js, auth.js. Keep routes thin, put logic in controllers.
07
Middleware
▼
JSMiddleware patterns
// Custom middleware
const logger = (req, res, next) => {
console.log(`${req.method} ${req.path}`);
next(); // MUST call next() or request hangs!
};
app.use(logger);
// Auth middleware
const protect = async (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch (err) {
res.status(401).json({ error: 'Invalid token' });
}
};
// Error handling middleware (4 params!)
app.use((err, req, res, next) => {
const status = err.statusCode || 500;
res.status(status).json({ error: err.message });
});
08
REST API
▼
JSComplete REST API controller
// controllers/userController.js
const User = require('../models/User');
exports.getUsers = async (req, res, next) => {
try {
const users = await User.find().select('-password');
res.json({ success: true, count: users.length, data: users });
} catch (err) {
next(err);
}
};
exports.createUser = async (req, res, next) => {
try {
const { name, email, password } = req.body;
const user = await User.create({ name, email, password });
res.status(201).json({ success: true, data: user });
} catch (err) {
if (err.code === 11000) {
return res.status(400).json({ error: 'Email already exists' });
}
next(err);
}
};
ℹ️
Use try/catch with async/await and pass errors to the error middleware via next(err) instead of crashing the server.
09
MongoDB with Mongoose
▼
JSMongoose models and queries
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
// Schema
const userSchema = new mongoose.Schema({
name: { type: String, required: true, trim: true },
email: { type: String, required: true, unique: true, lowercase: true },
password: { type: String, required: true, minlength: 6, select: false },
role: { type: String, enum: ['user','admin'], default: 'user' },
createdAt:{ type: Date, default: Date.now }
});
// Hook: hash password before save
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 12);
next();
});
const User = mongoose.model('User', userSchema);
// Queries
User.find({ role: 'admin' }).select('name email').sort('name').limit(10);
User.findById(id);
User.findByIdAndUpdate(id, { name: 'New' }, { new: true });
User.findByIdAndDelete(id);
User.countDocuments({ role: 'user' });
10
Mini Quizzes
▼
❓ Quiz 1
What does 'non-blocking I/O' mean in Node.js?
Node.js uses async I/O: when reading a file or DB query, it registers a callback and continues executing. The callback runs when data is ready. This allows handling thousands of concurrent connections on a single thread.
❓ Quiz 2
What's the difference between req.params and req.query?
req.params gets route parameters like /users/:id → req.params.id. req.query gets query string like /search?q=hello → req.query.q.