express, fastify, hyper-express, and koa are all server-side frameworks for Node.js that help developers build web applications and APIs. express is the most established option with a massive ecosystem of plugins and middleware. fastify focuses on high performance and low overhead, offering built-in validation and logging. koa is designed by the creators of Express to be more modern and modular, using async functions instead of callbacks. hyper-express aims to provide an Express-like interface with improved performance, often leveraging different underlying HTTP servers. Each tool solves the problem of routing and request handling but makes different trade-offs regarding speed, flexibility, and community support.
All four frameworks — express, fastify, hyper-express, and koa — help you build servers in Node.js. They handle routing, requests, and responses, but they differ in how they manage data flow, performance, and extensions. Let's look at how they handle real engineering tasks.
express uses a request-response middleware model.
req and res.next() to pass control to the next function.// express: Middleware chain
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
fastify uses an encapsulated plugin architecture.
next() callback pattern where possible.onRequest that are faster.// fastify: Hooks
fastify.addHook('onRequest', async (request, reply) => {
console.log('Time:', Date.now());
});
koa uses a context object and async functions.
req or res objects; everything is on ctx.await next() to flow through middleware.// koa: Context middleware
app.use(async (ctx, next) => {
console.log('Time:', Date.now());
await next();
});
hyper-express mimics Express but optimizes the underlying server.
req and res pattern for compatibility.// hyper-express: Express-like middleware
server.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
express handles validation via third-party middleware.
joi or express-validator.// express: External validation
app.post('/user', validationMiddleware, (req, res) => {
res.send(req.body);
});
fastify has schema validation built-in.
// fastify: Built-in schema
fastify.post('/user', {
schema: { body: { type: 'object', properties: { name: { type: 'string' } } } }
}, async (request, reply) => {
return request.body;
});
koa relies on community middleware for validation.
koa-bodyparser.// koa: External validation
app.use(bodyParser());
app.post('/user', async (ctx) => {
ctx.body = ctx.request.body;
});
hyper-express follows the Express pattern for validation.
// hyper-express: External validation
server.post('/user', validationMiddleware, (req, res) => {
res.send(req.body);
});
express uses a specific error-handling middleware signature.
(err, req, res, next).// express: Error handler
app.use((err, req, res, next) => {
res.status(500).send(err.message);
});
fastify handles errors via hooks or try/catch in handlers.
// fastify: Error handler
fastify.setErrorHandler((error, request, reply) => {
reply.status(500).send({ error: error.message });
});
koa uses a top-level try/catch in the app instance.
// koa: Error handler
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = 500;
ctx.body = err.message;
}
});
hyper-express mirrors Express error handling.
// hyper-express: Error handler
server.use((err, req, res, next) => {
res.status(500).send(err.message);
});
express has community-maintained types.
@types/express is standard but not perfect.// express: Type extension
interface Request {
user?: { id: string };
}
fastify is built with TypeScript in mind.
// fastify: Native types
fastify.get<{ Params: { id: string } }>('/user', async (req) => {
return req.params.id;
});
koa has good type support via @types/koa.
// koa: Context types
app.use(async (ctx: Koa.Context) => {
ctx.body = 'Hello';
});
hyper-express has limited type definitions.
// hyper-express: Basic types
server.use((req: Request, res: Response) => {
res.send('Hello');
});
express has the largest collection of plugins and tutorials.fastify is growing fast with a strong focus on quality.koa is stable but smaller than Express.hyper-express is niche with fewer resources.// Example: Finding middleware
// express: npm search 'express cors' yields many options
// fastify: npm search 'fastify cors' yields official plugin
fastify is engineered for speed and low overhead.hyper-express targets performance via underlying server swaps.express prioritizes stability over raw speed.koa is lighter than Express but not as fast as Fastify.// Example: Benchmarking setup
// All frameworks can be tested with autocannon or wrk
// Fastify typically leads in requests per second
express is mature with infrequent breaking changes.fastify follows semantic versioning strictly.koa is maintained by the Express team alumni.hyper-express has less visible long-term roadmaps.// Example: Version upgrades
// express: v4 to v5 took years, ensuring stability
// fastify: Regular major versions with clear migration paths
| Feature | express | fastify | koa | hyper-express |
|---|---|---|---|---|
| Architecture | Middleware (req/res) | Plugins & Hooks | Context (ctx) | Middleware (req/res) |
| Validation | External (3rd party) | Built-in (Schema) | External (3rd party) | External (3rd party) |
| Async Model | Callbacks / Promises | Async / Promises | Async / Await | Callbacks / Promises |
| TypeScript | Community Types | Native Types | Community Types | Limited Types |
| Performance | Standard | High | Medium | High |
express is the reliable workhorse 🐴. It is the default choice for most teams because it is easy to hire for and has a solution for everything. Use it for standard APIs where extreme performance is not the main bottleneck.
fastify is the speed demon 🏎️. It is the best choice for high-load microservices or when you want strong typing and validation without extra setup. It modernizes the Node.js server experience.
koa is the minimalist 🎨. It is perfect if you want to build your own framework on top of a solid async core. It removes legacy baggage but requires more decisions from you.
hyper-express is the specialist 🔧. Use it if you need Express compatibility but hit performance limits. Keep in mind the smaller community support when making this choice.
Final Thought: For most new projects today, fastify offers the best balance of speed and developer experience. However, express remains a safe and valid choice for teams prioritizing ecosystem size over raw performance.
Choose express if you need the largest ecosystem of middleware and tutorials. It is the safest bet for long-term stability and hiring developers who already know it. Ideal for standard REST APIs, legacy migrations, and projects where development speed matters more than raw performance.
Choose fastify if performance is a top priority or if you want built-in schema validation. It is excellent for microservices and high-throughput APIs. The plugin system is robust, and TypeScript support is first-class, making it great for large codebases.
Choose hyper-express if you need an Express-compatible API but require better performance for specific workloads like WebSockets. Be aware that the community is smaller, so finding third-party plugins or help might be harder. Best for niche cases where Express is too slow but you want similar syntax.
Choose koa if you prefer a lightweight, modern core without the baggage of legacy callbacks. It is suitable for developers who want to build their own middleware stack from scratch. Good for projects that value clean architecture and async/await flow over out-of-the-box features.
Fast, unopinionated, minimalist web framework for Node.js.
This project has a Code of Conduct.
import express from 'express'
const app = express()
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000')
})
This is a Node.js module available through the npm registry.
Before installing, download and install Node.js. Node.js 18 or higher is required.
If this is a brand new project, make sure to create a package.json first with
the npm init command.
Installation is done using the
npm install command:
npm install express
Follow our installing guide for more information.
PROTIP Be sure to read the migration guide to v5
The quickest way to get started with express is to utilize the executable express(1) to generate an application as shown below:
Install the executable. The executable's major version will match Express's:
npm install -g express-generator@4
Create the app:
express /tmp/foo && cd /tmp/foo
Install dependencies:
npm install
Start the server:
npm start
View the website at: http://localhost:3000
The Express philosophy is to provide small, robust tooling for HTTP servers, making it a great solution for single page applications, websites, hybrids, or public HTTP APIs.
Express does not force you to use any specific ORM or template engine. With support for over 14 template engines via @ladjs/consolidate, you can quickly craft your perfect framework.
To view the examples, clone the Express repository:
git clone https://github.com/expressjs/express.git --depth 1 && cd express
Then install the dependencies:
npm install
Then run whichever example you want:
node examples/content-negotiation
The Express.js project welcomes all constructive contributions. Contributions take many forms, from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more!
See the Contributing Guide for more technical details on contributing.
If you discover a security vulnerability in Express, please see Security Policies and Procedures.
To run the test suite, first install the dependencies:
npm install
Then run npm test:
npm test
For information about the governance of the express.js project, see GOVERNANCE.md.
The original author of Express is TJ Holowaychuk