Express.js is a minimal, unopinionated web framework for Node.js. Instead of forcing you into one way of building an app, it hands you a small toolkit — routing, middleware, and request/ response helpers — and lets you organize the rest however you like.
- Middleware-driven: almost everything in Express, from parsing a request body to logging, happens through middleware functions chained together.
- Flexible routing: you decide how routes, controllers, and folders are laid out.
- Plays well with others: pairs easily with MongoDB, PostgreSQL, MySQL, or any front-end framework.
- Scales down and up: fine for a weekend script, fine for a production API.
A tiny Express app
const express = require("express");
const app = express();
const PORT = 4000;
app.get("/", (req, res) => {
res.send("Task Manager API is running");
});
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}`);
});
Run it with node server.js, then open http://localhost:4000 in a browser — you'll see
"Task Manager API is running".
What happens under the hood
- A client (browser, mobile app, curl) sends a request to the server.
- The request passes through any middleware registered before the matching route — this is where logging, authentication, or body parsing usually happens.
- Express looks at the URL and HTTP verb and finds the matching route handler.
- The handler builds a response and hands it back.
- The response travels back to the client.
- If something throws along the way, error-handling middleware catches it so the server doesn't crash.
Why teams reach for Express
Express became the default choice for Node backends because it removes a lot of repetitive plumbing:
- Routing — map a URL and HTTP verb to a function.
app.get("/tasks", (req, res) => {
res.send("List of tasks");
});
- Middleware — functions that can inspect or modify
req/resbefore the final handler runs.
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} at ${new Date().toISOString()}`);
next();
});
- Error handling — a special four-argument middleware catches errors thrown anywhere in the chain.
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send("Something broke on our end");
});
Where Express is typically used
- Traditional server-rendered web apps and SPA backends
- REST APIs for CRUD-style resources
- Lightweight microservices
- Server-side rendering with template engines
- Reverse proxies / API gateways
- Rapid prototypes and internal tools