PermissiveMITTested by Geekflare

Fastify review

Node.js web framework with JSON Schema validation, a plugin system and built-in Pino logging

Data refreshedMethodologyHow we tested
Director of Geekflare

Rity Anand is a director of Geekflare. She has extensive experience managing business technology and a special interest in emerging technologies.

Verdict

Fastify is a good fit for Node.js APIs that want schema validation, typed routes and OpenAPI docs from official plugins, with encapsulated plugins that keep larger codebases in order. The catch is that the schema-first style and plugin encapsulation take some learning, and the project published many security advisories in the last year, mostly validation bypasses, so teams need to keep up with patch releases.

Best for

Teams building JSON APIs on Node.js that want validation and OpenAPI docs from one project

Not for

Teams that need Bun, Deno or edge runtimes, or want a full MVC framework with an ORM

Pros

  • Request validation and response serialisation from JSON Schema in the core
  • Official plugins for OpenAPI, WebSockets, JWT, OAuth2 and rate limits
  • Ships its own types, with type providers that type routes from schemas
  • Published support policy for each major version

Cons

  • Many security advisories in the last year, most about validation
  • Plugin encapsulation and schemas take time to learn
  • Node.js only, with no official Bun, Deno or Workers support
Ask Sparkian

Is Fastify right for your project?

Describe what you need and AI will check the fit against this review.

Or try:

Fastify features and capabilities

Schema validation and serialisation

Route schemas validate bodies, params, queries and headers and also speed up JSON output, so one schema covers input checks and response shape.

OpenAPI from routes

The official @fastify/swagger plugin builds an OpenAPI document from route schemas, and @fastify/swagger-ui serves it, so docs stay in step with the code.

Encapsulated plugins

Each plugin gets its own scope for routes, hooks and decorators, which lets teams split a large API into parts that cannot leak into each other.

Built-in logging

Turning on the Pino logger gives each request its own logger and an id, so structured request logs need no extra package.

Official auth plugins

JWT, OAuth2, sessions, basic and bearer auth come from the Fastify org, and @fastify/auth combines them per route.

TypeScript firstWritten in TypeScript or ships its own types, with typed routes or handlers
YesShips types; type providers type routes from schemas
Request validationValidates bodies, params or queries against a schema, in the core or an official package
YesJSON Schema in the core
OpenAPI docsGenerates an OpenAPI spec or Swagger UI from routes
YesOfficial @fastify/swagger plugin
Beyond Node.jsOfficially runs on Bun, Deno or edge runtimes such as Cloudflare Workers
NoNode.js only; AWS Lambda via @fastify/aws-lambda
WebSocketsBuilt in or through an official plugin
YesOfficial @fastify/websocket plugin
Project structureModules, dependency injection or a fixed layout, not only routing
PartlyEncapsulated plugins, autoload and awilix DI; no fixed layout
Database layerAn official ORM, query builder or data layer
PartlyOfficial connection plugins, no ORM
AuthenticationAn official auth module, plugin or strategy system
YesOfficial @fastify/auth, @fastify/jwt and @fastify/oauth2

At a glance

Type
Web framework
Stack
JavaScript / Node.js 20+
Databases
PostgreSQL, MySQL, MongoDB, Redis

Free vs paid editions

What you get when you self-host, and what needs a paid plan.

Fastify and its official plugins are free and have no paid edition or official hosting. It is an OpenJS Foundation project.

Running Fastify

Fastify 5 needs Node.js 20 or later, and TypeScript projects also install @types/node.

New cloud server to ready

4 s

Memory in use at idle

78 MB of 4 GB

Reads per second

19,918

Writes per second

12,288

Startup

0.44 s

Version tested

5.12.7 · Oct 31, 2026

  • The JSON Schema on the route did the validation, with no other dependency: 48 packages and 15 MB installed.
  • Reads had a median latency of 2.4 ms and 4.4 ms at the 99th percentile, the lowest of the seven.
  • By default the error names only the first invalid field. The price was also wrong, but only the name was reported.
app.js, after npm i fastify
import Fastify from "fastify";

// 100 items kept in memory, so the test measures the framework, not a database.
const items = new Map();
for (let i = 1; i <= 100; i++) items.set(i, { id: i, name: `Item ${i}`, price: i * 1.5, tags: ["sample"] });
let nextId = 101;
const app = Fastify();

app.get("/health", async () => ({ status: "ok" }));

app.get("/items/:id", async (req, reply) => {
  const item = items.get(Number(req.params.id));
  if (!item) return reply.code(404).send({ error: "Not found" });
  return item;
});

app.post("/items", {
  schema: {
    body: {
      type: "object",
      required: ["name", "price"],
      additionalProperties: false,
      properties: {
        name: { type: "string", minLength: 1, maxLength: 100 },
        price: { type: "number", minimum: 0 },
        tags: { type: "array", items: { type: "string" }, maxItems: 10 },
      },
    },
  },
}, async (req, reply) => {
  const item = { id: nextId++, ...req.body };
  items.set(item.id, item);
  return reply.code(201).send(item);
});

await app.listen({ port: Number(process.env.PORT ?? 3000), host: "127.0.0.1" });
OutputPassed5.12.7 · 400, Fastify's default error
Request: POST /items with {"name": "", "price": -1}
{
  "statusCode": 400,
  "code": "FST_ERR_VALIDATION",
  "error": "Bad Request",
  "message": "body/name must NOT have fewer than 1 characters"
}

What you can do with Fastify

Public JSON APIs with docs

Define each route with a schema and publish an OpenAPI document and Swagger UI from the same definitions.

Microservices on Node.js

Split services into encapsulated plugins with their own hooks, logging and database clients.

Real-time endpoints

Add WebSocket or server-sent event routes next to REST routes with the official @fastify/websocket and @fastify/sse plugins.