@fastify/websocket

Adds first-class WebSocket route support to Fastify, dispatching every upgrade through Fastify's own hooks and router instead of bolting ws on beside it.

Library
npm
v11.3.0
468stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity60
Maintenance72
Community80
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture78
Code Quality90
Innovation72
Learning Curve55

@fastify/websocket is the official Fastify plugin for handling WebSocket connections. Rather than treating WebSocket upgrades as a separate concern layered on top of the HTTP server, it dispatches every upgrade request through Fastify’s normal routing and hook pipeline — so onRequest, preValidation, and preHandler hooks, decorators, and encapsulation contexts all apply to WebSocket routes exactly as they do to regular HTTP routes. Routes opt in with a simple { websocket: true } route option, or a wsHandler alongside a normal handler when a single route needs to serve both HTTP and WebSocket clients.

Built on top of ws@8, the plugin runs the underlying WebSocket.Server in noServer mode and manages the upgrade handshake itself, giving applications a configurable errorHandler for connection-level errors and a preClose hook for graceful shutdown of open sockets. For testing, it decorates the Fastify instance with injectWS, which uses a Duplexify-based virtual socket pair to simulate a full WebSocket upgrade handshake without opening a real network connection — letting WebSocket routes be tested with the same ergonomics as Fastify’s regular .inject().

The project ships hand-written TypeScript type declarations (checked with tstyche type tests, not compiled from TS source), enforces 100% test coverage via c8, and is maintained by the Fastify core team as one of its official @fastify/* plugins.

What You Get

  • A { websocket: true } route option that upgrades a GET route to a WebSocket handler while still returning 404s for non-websocket clients hitting the same path if desired
  • Full Fastify hook support on WebSocket routes — onRequest, preParsing, preValidation, and preHandler all run before the socket is upgraded, so auth and validation logic is reused as-is
  • A configurable errorHandler that catches both synchronous/async errors thrown in the WS handler and error events from the established socket (e.g. unclean client disconnects)
  • An injectWS test helper that simulates a complete upgrade handshake via an in-memory Duplexify stream pair, avoiding real sockets in unit tests
  • A preClose hook (with a sane default) for cleanly closing all open WebSocket connections when the Fastify server shuts down
  • Access to the raw websocketServer (the underlying ws.Server instance) as a Fastify decoration for advanced use cases

Common Use Cases

  • Adding a single real-time endpoint (e.g. live notifications or a chat channel) to an existing Fastify HTTP API without standing up a separate WS server
  • Building an authenticated WebSocket API where preValidation/onRequest hooks verify a session or API key before the socket handshake completes
  • Serving both an HTTP JSON endpoint and a WebSocket stream from the same route path via the wsHandler + handler full-declaration syntax
  • Wrapping a Fastify WebSocket route in ws.createWebSocketStream to read/write it as a Node.js duplex stream instead of raw send/on('message') calls
  • Writing fast, deterministic unit tests for WebSocket routes using injectWS instead of spinning up a listening server and a real ws client

Under The Hood

Architecture The plugin is a single-file (index.js) Fastify plugin wrapped in fastify-plugin so its decorations and hooks escape Fastify’s normal encapsulation boundary. It decorates the instance with ws (a per-request boolean), websocketServer (the raw ws.Server, run in noServer mode), and injectWS (a testing helper). Its core trick is an onRoute hook that wraps every route’s handler: if the incoming request carries an upgrade socket, it hijacks the Fastify reply and dispatches to a wsHandler instead of the normal HTTP handler, routing the upgrade itself so all of Fastify’s own hooks and routing logic still apply. injectWS builds a virtual socket pair from two PassThrough streams joined by Duplexify, then emits a fake HTTP upgrade response through it — a deliberate low-level technique to make WebSocket routes testable without a real network socket. The design tightly couples this plugin to Fastify’s hook/route internals by intent — it is not a general-purpose module, but an integration layer.

Tech Stack Plain CommonJS JavaScript with hand-authored TypeScript declarations (types/index.d.ts), rather than a compiled TypeScript source. Runtime dependencies are minimal and precise: ws for the WebSocket protocol implementation, fastify-plugin for encapsulation-safe registration, and duplexify for the stream-pairing used by injectWS. It targets Fastify v5 as a peer plugin and uses Node’s built-in http, stream, and crypto modules directly rather than additional abstractions. Linting runs through neostandard’s flat ESLint config, type declarations are checked with tstyche, and coverage is measured with c8.

Code Quality The test suite spans four files covering base behavior, hooks, injectWS, and router interactions, run via Node’s built-in test runner under c8 --100 — meaning the project fails its own test command if coverage drops below 100%, a strong and unusually strict quality bar. Error handling is explicit: a documented, overridable errorHandler covers both handler exceptions and socket-level error events, with clear documentation of exactly which Fastify hooks run before versus after the WebSocket upgrade. CI runs on GitHub Actions, and the API is exercised through both runtime tests and static type tests, giving reasonable confidence in the shipped .d.ts file staying accurate.

What Makes It Unique Most WebSocket-on-HTTP-framework integrations treat the upgrade as a side channel bypassing the framework’s own middleware/hook pipeline. This plugin instead re-dispatches every upgrade through Fastify’s actual router, so authentication, validation, and other hooks apply identically to WebSocket and HTTP routes, and unmatched routes are still governed by Fastify’s normal 404 handling. Combined with the injectWS virtual-socket testing helper — a genuinely uncommon technique for making WebSocket routes as easy to unit test as regular HTTP routes — the library solves a real ergonomics gap rather than just wrapping ws in a thin decorator.

Used by 7 apps in this directory

Rust
67%
MIT

Bun

Developer Tools

95,895

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
64
Dependency
Built with
Rust67%
C++19%
Updated yesterday
TypeScript
99%
Apache 2.0

Colanode

Knowledge Management · Team Chat · Collaboration

5,097

Local-first, self-hosted workspace that combines real-time chat, Notion-style pages, and structured databases — all synced via CRDTs so you work offline without losing a keystroke.

View details
47
Repo Health
73
Technical
70
Dependency
Built with
TypeScript99%
Updated 5 months ago
TypeScript
97%
Other

Infisical

Security · Devops

29,145

The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.

View details
91
Repo Health
84
Technical
65
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
99%
Apache 2.0

Onlook

Design Tools · AI Design Tools

26,651

An open-source, AI-first visual editor that lets designers and developers build, style, and deploy React apps directly in code — no handoff required.

View details
68
Repo Health
80
Technical
67
Dependency
Built with
TypeScript99%
Updated 1 weeks ago
TypeScript
88%
AGPL 3.0

OpenPanel

Analytics

6,884

Open-source Mixpanel alternative with session replay, MCP integration, and privacy-first product analytics you fully control.

View details
74
Repo Health
74
Technical
68
Dependency
Built with
TypeScript88%
Updated 3 days ago
TypeScript
99%
MIT

optio

AI Agents · AI Code Assistants

1,043

Self-hosted AI agent workflow orchestration that runs on your Kubernetes cluster — from ticket intake to squash-merged PR, entirely within your infrastructure.

View details
75
Repo Health
81
Technical
70
Dependency
Built with
TypeScript99%
Updated 3 weeks ago
TypeScript
91%
MIT

Super Productivity

Productivity · Project Management

21,845

A privacy-respecting, local-first task manager with built-in timeboxing, Pomodoro timer, and deep integrations for Jira, GitHub, GitLab, and CalDAV — no accounts, no data collection, ever.

View details
90
Repo Health
81
Technical
72
Dependency
Built with
TypeScript91%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search