Node.js Frameworks, Compared Without the Marketing
Express, NestJS, Fastify, Koa, Hapi, AdonisJS and Hono. What each one optimises for, what it costs you, and what we ask a developer who says they know it. We do not sell framework opinions — we supply developers who work in the framework you already have.

The Framework Is Rarely What Is Hurting You
Every Node framework on this page routes a request, runs some functions in order, and hands you back a response. They differ in how much structure they impose and how much they do for you before your code runs. That difference matters, but it is smaller than the difference between a codebase with a boundary around its business logic and one without.
We see a lot of services where the team blames the framework. Nearly always the real problem is that domain logic lives inside route handlers, database calls are scattered through the request path, and nothing is tested, so every change is a gamble. That is true in Express, and it is equally true in NestJS with all the decorators in place.
So this page is here for two reasons. If you are choosing, it tells you what you actually gain and lose. If you are hiring, it tells you what a developer needs to understand in each one — which is what we screen for.
Hire Node.js developersSeven Frameworks and What They Are Actually For
Written for someone deciding what to build on, or trying to understand what a team inherited.
Express
- Still the default, and still a reasonable one
- A router and a middleware chain, and almost nothing else
- The largest ecosystem of packages and answers
- No opinions, so every team invents its own structure
NestJS
- Opinionated: modules, providers, dependency injection
- Decorators describe routing, validation and lifecycle
- Pays off when many people touch many modules
- Heavy for a small service that does one job
Fastify
- Built around throughput and low overhead per request
- JSON schema drives validation and fast serialisation
- Plugins are encapsulated, which is the good part and the confusing part
- Fewer copy-paste answers than Express when you get stuck
Koa
- From the people who wrote Express, deliberately leaner
- Async middleware with a context object and downstream-then-upstream flow
- No router, no body parsing, nothing bundled
- You assemble the stack, and you maintain that decision
Hapi
- Configuration-driven: a route is an object, not a chain of calls
- Validation, auth strategies and caching are first-class
- Explicit lifecycle rather than implicit middleware order
- Smaller community, so fewer developers have real exposure
AdonisJS
- Batteries included, in the way Laravel or Rails is
- ORM, auth, validation, migrations and a CLI in one box
- Fast for a small team shipping a whole product
- Opinions all the way down, and a narrower hiring pool
Hono
- Small and fast, aimed at edge and worker runtimes
- Web-standard request and response objects rather than Node-specific ones
- Good fit for thin API layers deployed close to users
- Constrained: not every Node API exists where it runs
Plain Node
- No framework at all is a legitimate answer for a tiny service
- Sensible when the service has two endpoints and no middleware
- Stops being sensible the moment you need auth and validation
- Teams that start here usually end up writing a worse Express
Where Next.js Sits
- Next.js route handlers cover many backend needs for a frontend-led app
- Fine until you need background jobs, queues or long-running work
- Often paired with a separate Node service rather than replaced by one
- A common reason clients need both a frontend and a backend hire
What Each One Optimises For, and What It Costs
No benchmark numbers here on purpose. Those go stale and they rarely describe your workload.
| Framework | Optimises for | Team size it suits | The main cost |
|---|---|---|---|
| Express | Familiarity, ecosystem reach, getting something running today | Any size, but especially one to four developers | No architecture is supplied, so the team has to impose one and keep enforcing it |
| NestJS | Consistency across many modules and many contributors | Five developers and up, or a small team that expects to grow | Boilerplate and a real learning curve; ceremony on a service with three endpoints |
| Fastify | Requests per second, and schema as the single source of truth | Any size that is comfortable writing schemas first | Plugin encapsulation surprises newcomers; fewer worked examples online |
| Koa | A minimal async middleware core with nothing you did not ask for | Small, senior teams who want to choose every piece | You own the assembly, and some community plugins are thinly maintained |
| Hapi | Declarative route configuration, built-in validation and auth | Teams who prefer configuration over convention | Smaller talent pool, and habits from Express do not transfer cleanly |
| AdonisJS | Shipping a complete product without choosing a stack piece by piece | One to five developers building the whole application | You live inside its opinions, and hiring for it is genuinely harder |
| Hono | Tiny footprint on edge, worker and serverless runtimes | Any size, usually for a thin API or gateway layer | Runtime constraints; code that assumes a full Node environment will not run |
If two rows look equally good for your situation, pick the one your current team already knows. The ramp-up cost of the unfamiliar option is real and immediate; the advantage of the better-fitting option is speculative and deferred.
Moving Between Frameworks, and Whether It Is Worth It
Most of the time, no. Here is how to tell when it is one of the exceptions.
What a Migration Actually Costs
Not the routes. Rewriting route definitions is the easy half of a week. The cost is everywhere else: middleware whose ordering carried unstated assumptions, error semantics that differ between frameworks, authentication that was wired into a specific request object, response shapes that quietly change, and every integration test that was written against the old behaviour. Plus a feature freeze, or a long period of maintaining two code paths.
The Reasons That Are Not Good Enough
A benchmark chart. A new senior hire who prefers something else. A conference talk. A vague sense that the codebase is messy — messy codebases migrate into messy codebases, because the mess is in the logic, not the router. And performance, unless you have profiled the service and can point at framework overhead rather than a slow query or an unindexed column.
The Reasons That Sometimes Are
The team has grown past the point where an unstructured codebase can absorb new people, and you have already tried conventions and code review and they did not stick. Or serialisation genuinely is the hot path and you have measured it. Or the framework you are on has no active maintenance and a security fix would be your problem. Or you are moving to an edge runtime where the current framework cannot run at all.
How to Do It If You Must
Not as a rewrite. Extract the business logic out of the handlers first, into plain functions with tests and no framework types in their signatures. That step alone delivers most of the benefit people expect from the migration. Then run both frameworks behind one proxy and move routes across a few at a time, oldest and least risky first, with the new path shadowed against the old before you switch traffic.
If you are not sure which side of this line you are on, a fixed-scope code audit answers it in writing before you commit anyone to the work.
What We Ask a Developer Who Claims to Know Each One
One question per framework that reliably separates real use from a weekend tutorial. All of these come out of live sessions on real code, never a quiz.
Express
What happens when an async route handler rejects and nothing catches it, and where an error-handling middleware has to be registered for it to run at all. Anyone who has debugged a hung request in production answers immediately. Anyone who has not will describe how middleware works in general and never reach the point.
NestJS
Explain provider scope, and what happens when two modules need each other. We are listening for whether they understand that a forward reference papers over a design problem rather than solving it, and whether they can describe what the injector is actually doing at startup.
Fastify
Why a decorator registered inside a plugin is not visible to a sibling plugin, and how you would deliberately share it. This is the single concept that separates people who have built a Fastify service from people who have added routes to one somebody else set up.
Koa
What the context object is, and what happens in a middleware after it awaits the next one. If they can describe the downstream-then-upstream flow and where they would put timing or error wrapping, they have written Koa middleware rather than just used it.
Hapi
How route-level validation relates to the request lifecycle, and where an extension point runs relative to authentication. Hapi rewards people who read the lifecycle; it punishes people who assume it behaves like a middleware chain.
AdonisJS
Describe a time the framework opinion did not match the requirement, and what you did. Every batteries-included framework produces this moment. A developer who has shipped with it has a story; a developer who followed the getting-started guide does not.
Hono
What breaks when code written for a Node server is deployed to an edge runtime. We want to hear about missing Node built-ins, execution time limits, and the difference between the web standard request object and the Node one — not a list of features.
Any of Them
Take one endpoint from a real service and ask what you would do to make it testable without starting the server. The answer tells us more about a backend developer than any framework question, because it shows whether they see the framework as a delivery mechanism or as the application itself.
What We Do Not Ask
Middleware signatures from memory, decorator names, configuration keys, or anything a developer looks up twice a year. We are not screening for recall. We are screening for whether they can reason about a request path they have never seen before, which is exactly what they will do in your codebase in week one.
What Goes Wrong, Whatever You Chose
These are the problems that actually wake people up. None of them is a framework problem.
The libraries that sit under all of this — the ORM, the queue, the validation layer, the auth pieces — are covered on the Node library page.
Tell Us the Framework, Not Just the Language
A brief that says Node gets you Node developers. A brief that says the framework, the database and the deployment target gets you people who are useful in week one.
Name the Stack
Framework, database and ORM, how it is deployed, and whether the codebase is new or inherited. Two paragraphs is plenty.
Get Profiles
Two or three pre-screened developers within three business days, each with the framework work they have actually done.
Interview Directly
Your process, your questions. Put them on your own codebase if that is how you normally assess.
They Join Your Team
Your standup, your board, your code review. Replacement at no cost if the fit is wrong inside the first two weeks.
Questions We Get About Framework Choice
Which Node.js framework should we pick for a new service?
Whichever one the people maintaining it already know, unless you have a specific reason to choose otherwise. Express if the team is small and wants to move now. NestJS if several developers will work across many modules and you want them to write the service the same way. Fastify if request and response shapes are well defined and you want schema validation and serialisation to come from one source. A framework chosen because it is fashionable costs you more in ramp-up than it ever returns in throughput.
Is it worth migrating an Express codebase to NestJS?
Usually not, and we will say so before we quote anything. The thing that hurts in an old Express service is almost never Express. It is business logic tangled into route handlers, no boundary around database access, and no tests. Extracting the logic into services and adding tests fixes the actual pain, and once that work is done the framework underneath matters much less. Migration earns its place when you have already tried that and the lack of a shared structure is still costing you on every new hire.
Can a developer who knows Express pick up Fastify or NestJS?
Most competent Node developers can, and the ramp is days rather than months. The exceptions are the parts that are genuinely different rather than cosmetic: the plugin encapsulation model in Fastify, and dependency injection and provider scope in NestJS. Someone who has only ever written Express tends to fight both for the first week because they expect everything to be in scope everywhere. We test for how quickly a candidate builds the correct mental model, not for whether they have the syntax memorised.
Do you supply developers for Koa, Hapi, AdonisJS or Hono?
Yes, though the pool is smaller than for Express, NestJS and Fastify and profiles can take slightly longer than the usual three business days. Tell us the framework in the brief so we screen for it rather than sending a strong Node developer who has never seen your stack. For the smaller frameworks we usually put forward someone with deep Node fundamentals plus real exposure to that framework, because fundamentals are what transfers.
Does the framework choice actually affect performance?
Less than the benchmarks suggest. In most services the time is spent in database queries, external API calls and serialising large payloads, not in the router. Framework overhead becomes visible when you are handling very high request rates with small, cheap handlers, or when serialisation itself is the hot path. Before changing framework for speed, profile the service. We have seen teams plan a rewrite and then find a single missing database index was the whole problem.
Do your developers work in our framework or recommend their own?
They work in yours. A developer joining your team does not get to restart your architecture, and anyone who opens with a rewrite proposal in week one has misunderstood the job. If they think a framework choice is genuinely hurting you, they raise it with evidence through your normal review process and you decide. The point of hiring a developer rather than an agency is that you keep the decisions.
Send Us the Stack, We Will Send the People
Express, NestJS, Fastify or something less common. Two or three vetted profiles back within three business days, and a replacement at no cost if the fit is wrong in the first two weeks.