🟢 Backend JavaScript
Node.js & Express Cheatsheet
Modules, file system, HTTP, Express routing, middleware and MongoDB — complete Node.js reference.
📖 10 sections
⏱ 22 min read
✅ Quizzes included
🌙 Dark mode
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.