Express.js
The most widely used Node.js web framework. Express is minimal and flexible, giving you full control over your server setup. Despite being older, it remains the most downloaded backend framework in the npm ecosystem by a wide margin.
Why Express.js?
You're building a Node.js REST API and want full control
Your team knows JavaScript/TypeScript well
You need a lightweight framework with a huge middleware ecosystem
Signal Breakdown
What drives the Trust Score
Download Trend
Last 12 months
Tradeoffs & Caveats
Know before you commitYou want built-in structure and conventions (try NestJS)
You want automatic API docs — Express requires manual OpenAPI setup
You're building a complex TypeScript app with decorators (NestJS is better)
Pricing
Free tier & paid plans
100% free, open-source (MIT)
Free & open-source
Hosting cost only — the framework is free
Alternative Tools
Other options worth considering
The most popular modern Python web framework for building APIs. FastAPI leverages Python type hints for automatic validation, serialization, and interactive OpenAPI docs. One of the fastest Python frameworks available.
Often Used Together
Complementary tools that pair well with Express.js
Learning Resources
Docs, videos, tutorials, and courses
Get Started
Repository and installation options
View on GitHub
github.com/expressjs/express
npm install expressQuick Start
Copy and adapt to get going fast
import express from 'express';
const app = express();
app.use(express.json());
app.get('/tools', async (req, res) => {
const tools = await db.query('SELECT * FROM tools ORDER BY trust_score DESC');
res.json(tools.rows);
});
app.post('/tools', async (req, res) => {
const { name, category } = req.body;
const tool = await db.insert('tools', { name, category });
res.status(201).json(tool);
});
app.listen(3000, () => console.log('API on :3000'));Code Examples
Common usage patterns
Middleware and error handling
Add auth middleware and a global error handler
import express, { Request, Response, NextFunction } from 'express';
// Auth middleware
function requireAuth(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
req.user = verifyToken(token);
next();
}
app.get('/protected', requireAuth, (req, res) => res.json(req.user));
// Global error handler (must be last)
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err.stack);
res.status(500).json({ error: err.message });
});Router modules
Split routes into separate files with Express Router
// routes/tools.ts
import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => { /* list */ });
router.post('/', async (req, res) => { /* create */ });
router.get('/:slug', async (req, res) => { /* get one */ });
export default router;
// app.ts
import toolsRouter from './routes/tools';
app.use('/api/tools', toolsRouter);Rate limiting with express-rate-limit
Protect your API from abuse
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 100,
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many requests' },
});
app.use('/api', limiter);Community Notes
Real experiences from developers who've used this tool